Import data
serology <- read_csv("./01_data/raw/FFI.peru.serology.kmeans2.csv") %>%
rename(ffi_is_code = Codigo) %>%
select(-1)
## New names:
## Rows: 3996 Columns: 25
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (6): hf, upch_ei_fecha, District, Communities, upch_ei_sexo, Location dbl (19):
## ...1, Codigo, age, Plate, pfmsp119, pfama1, gexp18, glurpr2, rh220...
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
ffi_individual <- read_csv("./01_data/raw/individuals_result_share_072022.csv")
## Warning: One or more parsing issues, see `problems()` for details
## Rows: 4000 Columns: 147
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (31): ffi_is_code, ffi_is_community, ffi_is_district, ffi_is_health_fac...
## dbl (99): ffi_is_sex, ffi_is_pregnancy, ffi_is_time_pregnancy, ffi_is_age, ...
## lgl (5): ffi_is_trip_last_symp_other_othr, ffi_micro_result_specie, ffi_mi...
## date (8): ffi_is_date, ffi_is_birth_date, ffi_is_antimal_drug_use_date, ffi...
## time (4): ffi_is_time_bath, ffi_is_time_wakeup, ffi_is_time_sleep, ffi_is_t...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ffi_household <- read_csv("./01_data/raw/household_gps_share_072022.csv")
## Rows: 980 Columns: 103
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (22): ffi_h_code, ffi_h_district, ffi_h_community, ffi_h_health_facilit...
## dbl (77): ffi_h_tot_family, ffi_h_tot_rooms, ffi_h_tot_beds, ffi_h_mti, ffi...
## lgl (2): ffi_h_material_floor_othr, ffi_h_fuel_kitchen_othr
## dttm (1): ffi_gps_time
## date (1): ffi_h_date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
data_2000_2019 <- read_csv("./01_data/raw/Data_FFI_2000_2019_20212405.csv")
## Rows: 31795 Columns: 23
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (6): Health Facility Name, Institution Type, Province, District, Facil...
## dbl (16): HFUID, RENAESID, Facility Network, Facility sub-network, Latitude...
## date (1): Date by month
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
data_2020_2021 <- read_csv("./01_data/raw/Data_FFI_2020_2021_20210629.csv")
## Rows: 1751 Columns: 23
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (6): Health Facility Name, Institution Type, Province, District, Facil...
## dbl (16): HFUID, RENAESID, Facility Network, Facility sub-network, Latitude...
## date (1): Date by month
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
poblacion <- readRDS("./01_data/raw/poblacion_inei_2017.rds")
Format data
ffi_total <- ffi_individual %>%
full_join(
serology %>%
mutate(
ffi_is_code = paste0(0, ffi_is_code)
),
by = "ffi_is_code"
)
ffi_total <- ffi_total %>%
mutate(
age_cat = case_when(
ffi_is_age_fixed >= 70 ~ "[70+)",
ffi_is_age_fixed >= 60 ~ "[60-70)",
ffi_is_age_fixed >= 50 ~ "[50-60)",
ffi_is_age_fixed >= 40 ~ "[40-50)",
ffi_is_age_fixed >= 30 ~ "[30-40)",
ffi_is_age_fixed >= 20 ~ "[20-30)",
ffi_is_age_fixed >= 10 ~ "[10-20)",
ffi_is_age_fixed >= 0 ~ "[0-10)"
),
age_cat = factor(age_cat),
age_code = case_when(
age_cat == "[70+)" ~ 8,
age_cat == "[60-70)" ~ 7,
age_cat == "[50-60)" ~ 6,
age_cat == "[40-50)" ~ 5,
age_cat == "[30-40)" ~ 4,
age_cat == "[20-30)" ~ 3,
age_cat == "[10-20)" ~ 2,
age_cat == "[0-10)" ~ 1,
),
gender = factor(
ffi_is_sex,
labels = c("Male", "Female")
),
ffi_is_malaria = factor(
ffi_is_malaria,
labels = c("No", "Yes", "Don't Know / No Answer")
),
across(
c(pf_recent:pv_historic),
~ factor(., labels = c("Negative", "Positive"))
),
across(
c(
ffi_is_fever_month,
ffi_is_antimal_drug_use,
ffi_is_mosq_net
),
~ factor(., labels = c("No", "Yes"))
),
ffi_is_trip_month = factor(
ffi_is_trip_month,
labels = c("No", "Yes", "Don't Know/No Answer")
),
ffi_is_mal_lifetime = factor(
ffi_is_mal_lifetime,
labels = c(
"1 to 3 times",
"3 to 7 times",
"More than 7 times"
)
),
ffi_is_place_shower = factor(
ffi_is_place_shower,
labels = c(
"Bathroom inside the dwelling",
"Bathroom outside the dwelling",
"In the countryside/river",
"Other"
)
),
education_level = case_when(
ffi_is_inst_level %in% 0 ~ "No schooling",
ffi_is_inst_level %in% 1:2 ~ "Primary school",
ffi_is_inst_level %in% 3:4 ~ "Secondary school",
ffi_is_inst_level %in% 5:6 ~ "Higher education"
),
education_level = fct_relevel(education_level, "No schooling",
"Primary school",
"Secondary school"),
economic_activities = factor(ffi_is_main_econ_act,
labels = c("Day labourer",
"Wood extractor",
"Fisherman",
"Livestock farmer",
"Farmer",
"Trader",
"Housewife",
"Student",
"Motorcycle taxi driver",
"None",
"Other")),
pv_exposure = case_when(
pv_recent == "Negative" & pv_historic == "Negative" ~ "Negative",
is.na(pv_recent) & is.na(pv_historic) ~ NA_character_,
TRUE ~ "Positive"
),
pf_exposure = case_when(
pf_recent == "Negative" & pf_historic == "Negative" ~ "Negative",
is.na(pf_recent) & is.na(pf_historic) ~ NA_character_,
TRUE ~ "Positive"
),
recent_exposure = case_when(
pv_recent == "Negative" & pf_recent == "Negative" ~ "Negative",
is.na(pv_recent) & is.na(pf_recent) ~ NA_character_,
TRUE ~ "Positive"
),
historical_exposure = case_when(
pv_historic == "Negative" & pf_historic == "Negative" ~ "Negative",
is.na(pv_historic) & is.na(pf_historic) ~ NA_character_,
TRUE ~ "Positive"
),
only_pv_exposure = case_when(
pv_exposure == "Positive" & pf_exposure == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
only_pf_exposure = case_when(
pf_exposure == "Positive" & pv_exposure == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
pv_pf_exposure = case_when(
pv_exposure == "Positive" & pf_exposure == "Positive" ~ "Positive",
TRUE ~ "Negative"
),
freedom_malaria = case_when(
pv_exposure == "Negative" & pf_exposure == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
only_pv_recent = case_when(
pv_recent == "Positive" & pf_recent == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
only_pf_recent = case_when(
pf_recent == "Positive" & pv_recent == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
pv_pf_recent = case_when(
pv_recent == "Positive" & pf_recent == "Positive" ~ "Positive",
TRUE ~ "Negative"
),
freedom_malaria_recent = case_when(
pv_recent == "Negative" & pf_recent == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
only_pv_historic = case_when(
pv_historic == "Positive" & pf_historic == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
only_pf_historic = case_when(
pf_historic == "Positive" & pv_historic == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
pv_pf_historic = case_when(
pv_historic == "Positive" & pf_historic == "Positive" ~ "Positive",
TRUE ~ "Negative"
),
freedom_malaria_historic = case_when(
pv_historic == "Negative" & pf_historic == "Negative" ~ "Positive",
TRUE ~ "Negative"
),
across(c(pv_exposure:freedom_malaria_historic), factor)
)
labelled::var_label(ffi_total) <- list(
ffi_is_district = "Districs",
gender = "Gender",
age_cat = "Age",
education_level = "Education Level",
economic_activities = "Economic Activities",
pf_recent = "Recent P. Falciparum",
pf_historic = "Historical P. Falciparum",
pv_recent = "Recent P. Vivax",
pv_historic = "Historical P. Vivax",
pv_exposure = "P. Vivax Exposure",
pf_exposure = "P. Falciparum Exposure"
)
saveRDS(ffi_total,
file = "01_data/processed/ffi_total.rds")
Table descriptive
library(gtsummary)
fisher.test.simulate.p.values <- function(data, variable, by, ...) {
result <- list()
test_results <- stats::fisher.test(data[[variable]], data[[by]], simulate.p.value = TRUE)
result$p <- test_results$p.value
result$test <- test_results$method
result
}
Table for district
table_1 <- ffi_total %>%
select(
ffi_is_district,
gender,
age_cat,
education_level,
economic_activities,
pf_recent:pv_historic
) %>%
tbl_summary(
by = "ffi_is_district",
missing_text = "Missing"
) %>%
add_n() %>%
add_overall() %>%
add_p(
test = list(all_categorical() ~ "fisher.test.simulate.p.values")
) %>%
bold_p() %>%
modify_header(label = "**Variable**") %>%
bold_labels()
table1
## # A tibble: 6 × 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Afghanistan 2000 2666 20595360
## 3 Brazil 1999 37737 172006362
## 4 Brazil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
table_1 %>%
as_flex_table() %>%
flextable::save_as_docx(path = "./02_output/reports/table1.docx")
Table for Plasmodium
table2 <- ffi_total %>%
select(
gender,
age_cat,
education_level,
economic_activities,
pf_exposure,
pv_exposure
) %>%
drop_na(pf_exposure, pv_exposure) %>%
pivot_longer(
cols = pv_exposure:pf_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "pv_exposure" ~ "P. Vivax Exposure",
exposure == "pf_exposure" ~ "P. Falciparum Exposure"
)
) %>%
tbl_strata(
strata = exposure,
.tbl_fun =
~ .x %>%
tbl_summary(
by = result_exposure,
missing_text = "Missing"
) %>%
add_p(
test = list(all_categorical() ~ "fisher.test.simulate.p.values")
) %>%
bold_p() %>%
modify_header(label = "**Variable**") %>%
bold_labels()
)
table2_overall <- ffi_total %>%
select(
gender,
age_cat,
education_level,
economic_activities,
pf_exposure,
pv_exposure
) %>%
drop_na(pf_exposure, pv_exposure) %>%
tbl_summary(
missing_text = "Missing"
) %>%
modify_header(
label = "**Variable**"
) %>%
bold_labels() %>%
modify_spanning_header(stat_0 ~ "**Overall**")
table2 <- tbl_merge(
tbls = list(table2, table2_overall),
tab_spanner = FALSE
)
table2
| Variable |
P. Falciparum Exposure
|
P. Vivax Exposure
|
Overall
|
|
Negative, N = 3,897
|
Positive, N = 99
|
p-value
|
Negative, N = 3,683
|
Positive, N = 313
|
p-value
|
N = 3,996
|
| Gender |
|
|
0.083 |
|
|
<0.001 |
|
| Male |
2,007 (52%) |
60 (61%) |
|
1,839 (50%) |
228 (73%) |
|
2,067 (52%) |
| Female |
1,890 (48%) |
39 (39%) |
|
1,844 (50%) |
85 (27%) |
|
1,929 (48%) |
| Age |
|
|
0.020 |
|
|
<0.001 |
|
| [0-10) |
1,075 (28%) |
15 (15%) |
|
1,089 (30%) |
1 (0.3%) |
|
1,090 (27%) |
| [10-20) |
905 (23%) |
19 (19%) |
|
913 (25%) |
11 (3.5%) |
|
924 (23%) |
| [20-30) |
372 (9.6%) |
8 (8.2%) |
|
360 (9.8%) |
20 (6.4%) |
|
380 (9.5%) |
| [30-40) |
423 (11%) |
11 (11%) |
|
380 (10%) |
54 (17%) |
|
434 (11%) |
| [40-50) |
350 (9.0%) |
13 (13%) |
|
300 (8.2%) |
63 (20%) |
|
363 (9.1%) |
| [50-60) |
332 (8.5%) |
14 (14%) |
|
285 (7.8%) |
61 (20%) |
|
346 (8.7%) |
| [60-70) |
212 (5.5%) |
8 (8.2%) |
|
177 (4.8%) |
43 (14%) |
|
220 (5.5%) |
| [70+) |
219 (5.6%) |
10 (10%) |
|
170 (4.6%) |
59 (19%) |
|
229 (5.7%) |
| Missing |
9 |
1 |
|
9 |
1 |
|
10 |
| Education Level |
|
|
0.020 |
|
|
<0.001 |
|
| No schooling |
754 (19%) |
10 (10%) |
|
743 (20%) |
21 (6.7%) |
|
764 (19%) |
| Primary school |
1,866 (48%) |
59 (60%) |
|
1,723 (47%) |
202 (65%) |
|
1,925 (48%) |
| Secondary school |
1,176 (30%) |
30 (30%) |
|
1,117 (30%) |
89 (28%) |
|
1,206 (30%) |
| Higher education |
98 (2.5%) |
0 (0%) |
|
97 (2.6%) |
1 (0.3%) |
|
98 (2.5%) |
| Missing |
3 |
0 |
|
3 |
0 |
|
3 |
| Economic Activities |
|
|
<0.001 |
|
|
<0.001 |
|
| Day labourer |
854 (22%) |
13 (13%) |
|
847 (23%) |
20 (6.4%) |
|
867 (22%) |
| Wood extractor |
30 (0.8%) |
3 (3.1%) |
|
27 (0.7%) |
6 (1.9%) |
|
33 (0.8%) |
| Fisherman |
25 (0.6%) |
2 (2.0%) |
|
20 (0.5%) |
7 (2.2%) |
|
27 (0.7%) |
| Livestock farmer |
72 (1.8%) |
3 (3.1%) |
|
62 (1.7%) |
13 (4.2%) |
|
75 (1.9%) |
| Farmer |
1 (<0.1%) |
0 (0%) |
|
1 (<0.1%) |
0 (0%) |
|
1 (<0.1%) |
| Trader |
873 (22%) |
37 (38%) |
|
723 (20%) |
187 (60%) |
|
910 (23%) |
| Housewife |
100 (2.6%) |
4 (4.1%) |
|
99 (2.7%) |
5 (1.6%) |
|
104 (2.6%) |
| Student |
656 (17%) |
16 (16%) |
|
619 (17%) |
53 (17%) |
|
672 (17%) |
| Motorcycle taxi driver |
1,128 (29%) |
19 (19%) |
|
1,136 (31%) |
11 (3.5%) |
|
1,147 (29%) |
| None |
21 (0.5%) |
0 (0%) |
|
20 (0.5%) |
1 (0.3%) |
|
21 (0.5%) |
| Other |
135 (3.5%) |
1 (1.0%) |
|
126 (3.4%) |
10 (3.2%) |
|
136 (3.4%) |
| Missing |
2 |
1 |
|
3 |
0 |
|
3 |
| P. Falciparum Exposure |
|
|
|
|
|
|
|
| Negative |
|
|
|
|
|
|
3,897 (98%) |
| Positive |
|
|
|
|
|
|
99 (2.5%) |
| P. Vivax Exposure |
|
|
|
|
|
|
|
| Negative |
|
|
|
|
|
|
3,683 (92%) |
| Positive |
|
|
|
|
|
|
313 (7.8%) |
table2 %>%
as_flex_table() %>%
flextable::save_as_docx(path = "./02_output/reports/table2.docx")
Table for Exposure Time
table3 <- ffi_total %>%
select(
gender,
age_cat,
education_level,
economic_activities,
recent_exposure,
historical_exposure
) %>%
drop_na(recent_exposure, historical_exposure) %>%
pivot_longer(
cols = recent_exposure:historical_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "recent_exposure" ~ "Recent Exposure",
exposure == "historical_exposure" ~ "Historical Exposure"
)
) %>%
tbl_strata(
strata = exposure,
.tbl_fun =
~ .x %>%
tbl_summary(
by = result_exposure,
missing_text = "Missing"
) %>%
add_p(
test = list(all_categorical() ~ "fisher.test.simulate.p.values")
) %>%
bold_p() %>%
modify_header(label = "**Variable**") %>%
bold_labels()
)
table3_overall <- ffi_total %>%
select(
gender,
age_cat,
education_level,
economic_activities,
recent_exposure,
historical_exposure
) %>%
drop_na(recent_exposure, historical_exposure) %>%
tbl_summary(
missing_text = "Missing"
) %>%
modify_header(
label = "**Variable**"
) %>%
bold_labels() %>%
modify_spanning_header(stat_0 ~ "**Overall**")
table3 <- tbl_merge(
tbls = list(table3, table3_overall),
tab_spanner = FALSE
)
table3
| Variable |
Historical Exposure
|
Recent Exposure
|
Overall
|
|
Negative, N = 3,728
|
Positive, N = 268
|
p-value
|
Negative, N = 3,793
|
Positive, N = 203
|
p-value
|
N = 3,996
|
| Gender |
|
|
<0.001 |
|
|
<0.001 |
|
| Male |
1,886 (51%) |
181 (68%) |
|
1,910 (50%) |
157 (77%) |
|
2,067 (52%) |
| Female |
1,842 (49%) |
87 (32%) |
|
1,883 (50%) |
46 (23%) |
|
1,929 (48%) |
| Age |
|
|
<0.001 |
|
|
<0.001 |
|
| [0-10) |
1,085 (29%) |
5 (1.9%) |
|
1,079 (29%) |
11 (5.5%) |
|
1,090 (27%) |
| [10-20) |
899 (24%) |
25 (9.3%) |
|
918 (24%) |
6 (3.0%) |
|
924 (23%) |
| [20-30) |
366 (9.8%) |
14 (5.2%) |
|
366 (9.7%) |
14 (7.0%) |
|
380 (9.5%) |
| [30-40) |
392 (11%) |
42 (16%) |
|
406 (11%) |
28 (14%) |
|
434 (11%) |
| [40-50) |
309 (8.3%) |
54 (20%) |
|
327 (8.6%) |
36 (18%) |
|
363 (9.1%) |
| [50-60) |
303 (8.1%) |
43 (16%) |
|
305 (8.1%) |
41 (20%) |
|
346 (8.7%) |
| [60-70) |
182 (4.9%) |
38 (14%) |
|
197 (5.2%) |
23 (11%) |
|
220 (5.5%) |
| [70+) |
182 (4.9%) |
47 (18%) |
|
187 (4.9%) |
42 (21%) |
|
229 (5.7%) |
| Missing |
10 |
0 |
|
8 |
2 |
|
10 |
| Education Level |
|
|
<0.001 |
|
|
<0.001 |
|
| No schooling |
747 (20%) |
17 (6.3%) |
|
745 (20%) |
19 (9.4%) |
|
764 (19%) |
| Primary school |
1,754 (47%) |
171 (64%) |
|
1,792 (47%) |
133 (66%) |
|
1,925 (48%) |
| Secondary school |
1,126 (30%) |
80 (30%) |
|
1,156 (31%) |
50 (25%) |
|
1,206 (30%) |
| Higher education |
98 (2.6%) |
0 (0%) |
|
97 (2.6%) |
1 (0.5%) |
|
98 (2.5%) |
| Missing |
3 |
0 |
|
3 |
0 |
|
3 |
| Economic Activities |
|
|
<0.001 |
|
|
<0.001 |
|
| Day labourer |
849 (23%) |
18 (6.7%) |
|
848 (22%) |
19 (9.4%) |
|
867 (22%) |
| Wood extractor |
29 (0.8%) |
4 (1.5%) |
|
28 (0.7%) |
5 (2.5%) |
|
33 (0.8%) |
| Fisherman |
21 (0.6%) |
6 (2.2%) |
|
22 (0.6%) |
5 (2.5%) |
|
27 (0.7%) |
| Livestock farmer |
63 (1.7%) |
12 (4.5%) |
|
67 (1.8%) |
8 (3.9%) |
|
75 (1.9%) |
| Farmer |
1 (<0.1%) |
0 (0%) |
|
1 (<0.1%) |
0 (0%) |
|
1 (<0.1%) |
| Trader |
770 (21%) |
140 (52%) |
|
787 (21%) |
123 (61%) |
|
910 (23%) |
| Housewife |
99 (2.7%) |
5 (1.9%) |
|
100 (2.6%) |
4 (2.0%) |
|
104 (2.6%) |
| Student |
623 (17%) |
49 (18%) |
|
646 (17%) |
26 (13%) |
|
672 (17%) |
| Motorcycle taxi driver |
1,124 (30%) |
23 (8.6%) |
|
1,139 (30%) |
8 (3.9%) |
|
1,147 (29%) |
| None |
20 (0.5%) |
1 (0.4%) |
|
21 (0.6%) |
0 (0%) |
|
21 (0.5%) |
| Other |
127 (3.4%) |
9 (3.4%) |
|
131 (3.5%) |
5 (2.5%) |
|
136 (3.4%) |
| Missing |
2 |
1 |
|
3 |
0 |
|
3 |
| recent_exposure |
|
|
|
|
|
|
|
| Negative |
|
|
|
|
|
|
3,793 (95%) |
| Positive |
|
|
|
|
|
|
203 (5.1%) |
| historical_exposure |
|
|
|
|
|
|
|
| Negative |
|
|
|
|
|
|
3,728 (93%) |
| Positive |
|
|
|
|
|
|
268 (6.7%) |
table3 %>%
as_flex_table() %>%
flextable::save_as_docx(path = "./02_output/reports/table3.docx")
Distance communities and regional Hospital
iquitos_centro <- tibble(
"ffi_h_health_facility_name" = "Hospital Regional de Loreto",
Longitude = -73.25385902080906,
Latitude = -3.7264060164148716,
) %>%
st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326) %>%
st_transform(crs = 32718)
communities_sf <- ffi_household %>%
select(
ffi_h_district,
ffi_h_code_community,
ffi_h_community,
ffi_gps_long,
ffi_gps_lat
) %>%
st_as_sf(
coords = c("ffi_gps_long", "ffi_gps_lat"),
crs = 4326
) %>%
group_by(ffi_h_district, ffi_h_code_community, ffi_h_community) %>%
summarise() %>%
st_centroid()
## `summarise()` has grouped output by 'ffi_h_district', 'ffi_h_code_community'.
## You can override using the `.groups` argument.
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
communities_distances <- communities_sf %>%
st_transform(crs = 32718) %>%
st_distance(iquitos_centro)
communities_distances <- enframe(communities_distances) %>%
mutate(
ffi_is_cod_com = communities_sf$ffi_h_code_community,
ffi_is_community = communities_sf$ffi_h_community,
distance = as.numeric(value)
) %>%
select(-c(name, value))
Las Comunidades mas cercanas y mas lejanas por distrito:
communities_distances %>%
mutate(
ffi_h_district = communities_sf$ffi_h_district
) %>%
group_by(ffi_h_district) %>%
slice_min(distance, n = 1) %>%
bind_rows(
communities_distances %>%
mutate(
ffi_h_district = communities_sf$ffi_h_district
) %>%
group_by(ffi_h_district) %>%
slice_max(distance, n = 1)
) %>%
arrange(ffi_h_district, distance)
Plots
Malaria Annual Parasite Index
data_malaria <- bind_rows(
data_2000_2019,
data_2020_2021
) %>%
drop_na(District)
pob_loreto <- poblacion %>%
filter(dep == "LORETO") %>%
select(District = distr, Total)
malaria_cases_pob <- data_malaria %>%
rowwise() %>%
mutate(
cases_malaria = sum(
c_across(c(
`Confirmed P. Falciparum`,
`Confirmed P. Vivax`
)),
na.rm = TRUE
)
) %>%
group_by(District) %>%
summarise(cases_malaria = sum(cases_malaria))
malaria_cases_pob <- malaria_cases_pob %>%
left_join(
pob_loreto
) %>%
mutate(
api = cases_malaria * 1000 / Total
)
## Joining, by = "District"
data(Peru, package = "innovar")
malaria_cases_pob_sf <- Peru %>%
filter(dep == "LORETO") %>%
select(District = distr, geometry) %>%
right_join(
malaria_cases_pob
)
## Joining, by = "District"
figure1 <- ggplot(malaria_cases_pob_sf) +
geom_sf(aes(fill = api, geometry = geometry)) +
geom_sf(data = malaria_cases_pob_sf %>% dplyr::filter(District == "BELEN"), colour = "#aa6439", fill = NA, size = 1.5, aes(fill = api, geometry = geometry)) +
geom_sf(data = malaria_cases_pob_sf %>% dplyr::filter(District == "INDIANA"), colour = "#256e5d", fill = NA, size = 1.5, aes(fill = api, geometry = geometry)) +
scale_fill_distiller(
name = "API",
na.value = "black",
# limits = c(0, 4000),
palette = "RdYlGn",
direction = -1,
breaks = scales::pretty_breaks(n = 5),
values = c(
0,
0.001,
0.002,
0.005,
0.008,
0.01,
0.02,
0.03,
0.05,
0.1,
0.6,
0.9,
1
)
) +
labs(
x = NULL,
y = NULL,
title = NULL
) +
theme_classic() +
geom_sf_label_repel(
data = malaria_cases_pob_sf %>% dplyr::filter(District == "BELEN"),
aes(label = District),
min.segment.length = 0,
force = 100,
nudge_x = -1,
seed = 10,
colour = "#aa6439"
) +
geom_sf_label_repel(
data = malaria_cases_pob_sf %>% dplyr::filter(District == "INDIANA"),
aes(label = District),
min.segment.length = 0,
force = 100,
nudge_x = 1,
seed = 10,
colour = "#256e5d"
)
figure1
## Warning in st_point_on_surface.sfc(data$geometry): st_point_on_surface may not
## give correct results for longitude/latitude data
## Warning in st_point_on_surface.sfc(data$geometry): st_point_on_surface may not
## give correct results for longitude/latitude data

ggsave(
"./02_output/plots/figure1.png",
figure1,
device = grDevices::png,
dpi = 300
)
Serological Results
By communities and type of plasmodium/time
# ffi_total %>%
# ggplot(aes(
# x = ffi_is_community,
# fill = pv_historic
# )) +
# coord_flip(ylim = c(0, 0.25)) +
# geom_bar(position = "fill")
plot1 <- ffi_total %>%
drop_na(pf_recent:pv_historic) %>%
left_join(
communities_distances
) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
ffi_is_community = str_to_title(ffi_is_community),
ffi_is_community = paste0(
ffi_is_community,
" (",
str_to_title(ffi_is_district),
")"
),
ffi_is_community = fct_reorder(
ffi_is_community,
distance,
.desc = TRUE
)
) %>%
ggplot(aes(
x = ffi_is_community,
fill = result_malaria
)) +
facet_wrap(vars(malaria)) +
geom_bar(position = "fill", color = "black") +
coord_flip(ylim = c(0, 0.25)) +
scale_y_continuous(
labels = scales::percent_format()
) +
#ggsci::scale_fill_lancet() +
innovar::scale_fill_innova("npr") +
labs(
x = "Communities",
y = "Percentage"
) +
guides(
fill = guide_legend("Results")
) +
theme_minimal() +
theme(
strip.text = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold",
size = 11
),
legend.title = element_text(
face = "bold",
size = 11
)
)
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1

ggsave(
"./02_output/plots/plot1_typeofmalaria_communities.png",
plot1,
dpi = 300,
bg = "white",
width = 10,
height = 9
)
By communities, Indiana and type of plasmodium/time
plot1_indiana <- ffi_total %>%
drop_na(pf_recent:pv_historic) %>%
left_join(
communities_distances
) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
ffi_is_community = str_to_title(ffi_is_community)
) %>%
filter(ffi_is_district == "INDIANA") %>%
mutate(
ffi_is_community = fct_reorder(
ffi_is_community,
distance,
.desc = TRUE
)
) %>%
ggplot(aes(
x = ffi_is_community,
fill = result_malaria
)) +
facet_wrap(vars(malaria)) +
geom_bar(position = "fill", color = "black") +
coord_flip(ylim = c(0, 0.25)) +
scale_y_continuous(
labels = scales::percent_format()
) +
#ggsci::scale_fill_lancet() +
innovar::scale_fill_innova("npr") +
labs(
title = str_wrap("Serological results by plasmodium type of malaria in the Indiana District", 100),
x = "Communities",
y = "Percentage"
) +
guides(
fill = guide_legend("Results")
) +
theme_minimal() +
theme(
strip.text = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold",
size = 11
),
legend.title = element_text(
face = "bold",
size = 11
)
)
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1_indiana

ggsave(
"./02_output/plots/plot1_typeofmalaria_communities_indiana.png",
plot1_indiana,
dpi = 300,
bg = "white",
width = 10,
height = 9
)
By communities, Belen and type of plasmodium/time
plot1_belen <- ffi_total %>%
drop_na(pf_recent:pv_historic) %>%
left_join(
communities_distances
) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
filter(ffi_is_district == "BELEN") %>%
mutate(
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
ffi_is_community = str_to_title(ffi_is_community),
ffi_is_community = fct_reorder(
ffi_is_community,
distance,
.desc = TRUE
)
) %>%
ggplot(aes(
x = ffi_is_community,
fill = result_malaria
)) +
facet_wrap(vars(malaria)) +
geom_bar(position = "fill", color = "black") +
coord_flip(ylim = c(0, 0.25)) +
scale_y_continuous(
labels = scales::percent_format()
) +
#ggsci::scale_fill_lancet() +
innovar::scale_fill_innova("npr") +
labs(
title = str_wrap("Serological results by plasmodium type of malaria in the Belen District", 100),
x = "Communities",
y = "Percentage"
) +
guides(
fill = guide_legend("Results")
) +
theme_minimal() +
theme(
strip.text = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold",
size = 11
),
legend.title = element_text(
face = "bold",
size = 11
)
)
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot1_belen

ggsave(
"./02_output/plots/plot1_typeofmalaria_communities_belen.png",
plot1_belen,
dpi = 300,
bg = "white",
width = 10,
height = 9
)
By communities, type of plasmodium exposure
plot2 <- ffi_total %>%
drop_na(pf_exposure, pv_exposure) %>%
left_join(
communities_distances
) %>%
pivot_longer(
cols = pv_exposure:pf_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "pv_exposure" ~ "P. Vivax Exposure",
exposure == "pf_exposure" ~ "P. Falciparum Exposure"
),
ffi_is_community = str_to_title(ffi_is_community),
ffi_is_community = fct_reorder(
ffi_is_community,
distance,
.desc = TRUE
)
) %>%
ggplot(aes(
x = ffi_is_community,
fill = result_exposure
)) +
facet_wrap(vars(exposure)) +
geom_bar(position = "fill", color = "black") +
coord_flip(ylim = c(0, 0.40)) +
scale_y_continuous(
labels = scales::percent_format()
) +
# ggsci::scale_fill_lancet() +
innovar::scale_fill_innova("npr") +
labs(
x = "Communities",
y = "Percentage"
) +
guides(
fill = guide_legend("Results")
) +
theme_minimal() +
theme(
strip.text = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold",
size = 11
),
legend.title = element_text(
face = "bold",
size = 11
)
)
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot2

ggsave(
"./02_output/plots/plot2_typeofmalaria_communities.png",
plot2,
dpi = 300,
bg = "white",
width = 10,
height = 9
)
By communities, time of plasmodium exposure
plot3 <- ffi_total %>%
drop_na(recent_exposure, historical_exposure) %>%
left_join(
communities_distances
) %>%
pivot_longer(
cols = recent_exposure:historical_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "recent_exposure" ~ "Recent Exposure",
exposure == "historical_exposure" ~ "Historical Exposure"
),
ffi_is_community = str_to_title(ffi_is_community),
ffi_is_community = fct_reorder(
ffi_is_community,
distance,
.desc = TRUE
)
) %>%
ggplot(aes(
x = ffi_is_community,
fill = result_exposure
)) +
facet_wrap(vars(exposure)) +
geom_bar(position = "fill", color = "black") +
coord_flip(ylim = c(0, 0.30)) +
scale_y_continuous(
labels = scales::percent_format()
) +
# ggsci::scale_fill_lancet() +
innovar::scale_fill_innova("npr") +
labs(
x = "Communities",
y = "Percentage"
) +
guides(
fill = guide_legend("Results")
) +
theme_minimal() +
theme(
strip.text = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold",
size = 11
),
legend.title = element_text(
face = "bold",
size = 11
)
)
## Joining, by = c("ffi_is_community", "ffi_is_cod_com")
plot3

ggsave(
"./02_output/plots/plot3_typeofmalaria_communities.png",
plot3,
dpi = 300,
bg = "white",
width = 10,
height = 9
)
# ffi_total %>%
# drop_na(pf_recent:pv_historic, age_cat) %>%
# pivot_longer(
# cols = pf_recent:pv_historic,
# names_to = "malaria",
# values_to = "result_malaria"
# ) %>%
# mutate(
# result_malaria = case_when(
# result_malaria == "Positive" ~ 1,
# TRUE ~ 0
# ),
# malaria = case_when(
# malaria == "pf_recent" ~ "Recent P. Falciparum",
# malaria == "pf_historic" ~ "Historical P. Falciparum",
# malaria == "pv_recent" ~ "Recent P. Vivax",
# malaria == "pv_historic" ~ "Historical P. Vivax"
# ),
# ffi_is_community = str_to_title(ffi_is_community)
# ) %>%
# group_by(ffi_is_community, age_cat, malaria) %>%
# summarise(result_malaria = mean(result_malaria)) %>%
# ggplot(
# aes(
# x = age_cat,
# y = result_malaria,
# color = malaria,
# group = malaria
# )
# ) +
# geom_point() +
# geom_line() +
# facet_wrap(vars(ffi_is_community)) +
# theme_bw()
Seropositivity 4 malaria
By district
sero_4malaria_district <- ffi_total %>%
drop_na(pf_recent:pv_historic, age_cat) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_district, age_cat, malaria) %>%
summarise(result_malaria = mean(result_malaria)) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_district)) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.40)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
sero_4malaria_district

ggsave(
"./02_output/plots/plot4_sero_4malaria_district.png",
sero_4malaria_district,
dpi = 300,
bg = "white",
width = 12,
height = 7.5
)
By Health Facility
sero_4malaria_hf <- ffi_total %>%
drop_na(pf_recent:pv_historic, age_cat) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
),
ffi_is_health_facility_name = paste(
ffi_is_district,
ffi_is_health_facility_name,
sep = " - "
)
) %>%
group_by(ffi_is_health_facility_name, age_cat, malaria) %>%
summarise(result_malaria = mean(result_malaria)) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_health_facility_name)) +
scale_y_continuous(
labels = scales::percent_format()
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw() +
theme(
axis.text.x = element_text(
angle = 45,
vjust = 1,
hjust = 1
)
)
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_4malaria_hf

ggsave(
"./02_output/plots/plot5_sero_4malaria_hf.png",
sero_4malaria_hf,
dpi = 300,
bg = "white",
width = 10,
height = 7
)
Seopositivity by Type of Malaria
By District
ffi_typeof_malaria <- ffi_total %>%
drop_na(pf_exposure, pv_exposure, age_cat) %>%
pivot_longer(
cols = pv_exposure:pf_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "pv_exposure" ~ "P. Vivax Exposure",
exposure == "pf_exposure" ~ "P. Falciparum Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
)
sero_typeofmalaria_district <- ffi_typeof_malaria %>%
group_by(ffi_is_district, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure)) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_district)) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.40)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
ggsave(
"./02_output/plots/plot6_sero_typeofmalaria_district.png",
sero_typeofmalaria_district,
dpi = 300,
bg = "white",
width = 12,
height = 7.5
)
By Health Facility
sero_typeofmalaria_hf <- ffi_typeof_malaria %>%
group_by(ffi_is_health_facility_name, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure)) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_health_facility_name)) +
scale_y_continuous(
labels = scales::percent_format()
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_typeofmalaria_hf

ggsave(
"./02_output/plots/plot7_sero_typeofmalaria_hf.png",
sero_typeofmalaria_hf,
dpi = 300,
bg = "white",
width = 13,
height = 9
)
Seropositivity by Time of Exposure
By District
ffi_timeofmalaria <- ffi_total %>%
drop_na(recent_exposure, historical_exposure, age_cat) %>%
pivot_longer(
cols = recent_exposure:historical_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "recent_exposure" ~ "Recent Exposure",
exposure == "historical_exposure" ~ "Historical Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
)
sero_timeofmalaria_district <- ffi_timeofmalaria %>%
group_by(ffi_is_district, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure)) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_district)) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.40)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat'. You can
## override using the `.groups` argument.
ggsave(
"./02_output/plots/plot8_sero_timeofmalaria_district.png",
sero_timeofmalaria_district,
dpi = 300,
bg = "white",
width = 12,
height = 7.5
)
By Health Facility
sero_timeofmalaria_hf <- ffi_timeofmalaria %>%
group_by(ffi_is_health_facility_name, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure)) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_wrap(vars(ffi_is_health_facility_name)) +
scale_y_continuous(
labels = scales::percent_format()
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_health_facility_name', 'age_cat'.
## You can override using the `.groups` argument.
sero_timeofmalaria_hf

ggsave(
"./02_output/plots/plot9_sero_timeofmalaria_hf.png",
sero_timeofmalaria_hf,
dpi = 300,
bg = "white",
width = 13,
height = 9
)
Relation with sex
library(rlang)
##
## Attaching package: 'rlang'
## The following objects are masked from 'package:purrr':
##
## %@%, as_function, flatten, flatten_chr, flatten_dbl, flatten_int,
## flatten_lgl, flatten_raw, invoke, splice
seropositivy_summarise <- function(data, type, variable, ...) {
if (type == "4malaria") {
ffi_total %>%
drop_na(pf_recent:pv_historic, {{ variable }}, ...) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_district, {{ variable }}, ..., malaria) %>%
summarise(result_malaria = mean(result_malaria))
} else if (type == "typeofmalaria" ) {
ffi_total %>%
drop_na(pf_exposure, pv_exposure, {{ variable }}, ...) %>%
pivot_longer(
cols = pv_exposure:pf_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "pv_exposure" ~ "P. Vivax Exposure",
exposure == "pf_exposure" ~ "P. Falciparum Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_district, {{ variable }}, ..., exposure) %>%
summarise(result_exposure = mean(result_exposure))
} else if (type == "timeofmalaria") {
ffi_total %>%
drop_na(recent_exposure, historical_exposure,
{{ variable }}, ...) %>%
pivot_longer(
cols = recent_exposure:historical_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "recent_exposure" ~ "Recent Exposure",
exposure == "historical_exposure" ~ "Historical Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_district, {{ variable }}, ..., exposure) %>%
summarise(result_exposure = mean(result_exposure))
}
}
By 4 Malaria
sero_4malaria_district_gender <- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
gender
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.40)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_4malaria_district_gender

ggsave(
"./02_output/plots/plot10_sero_4malaria_district_gender.png",
sero_4malaria_district_gender,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_gender <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
gender
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_typeofmalaria_district_gender

ggsave(
"./02_output/plots/plot11_sero_typeofmalaria_district_gender.png",
sero_typeofmalaria_district_gender,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_gender <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
gender
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_timeofmalaria_district_gender

ggsave(
"./02_output/plots/plot12_sero_timeofmalaria_district_gender.png",
sero_timeofmalaria_district_gender,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with Education Level
By 4 Malaria
sero_4malaria_district_edulevel <- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
education_level
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(education_level),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.40)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_4malaria_district_edulevel

ggsave(
"./02_output/plots/plot13_sero_4malaria_district_edulevel.png",
sero_4malaria_district_edulevel,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_edulevel <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
education_level
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(education_level),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_typeofmalaria_district_edulevel

ggsave(
"./02_output/plots/plot14_sero_typeofmalaria_district_edulevel.png",
sero_typeofmalaria_district_edulevel,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_edulevel <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
education_level
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(education_level),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'education_level'. You can override using the `.groups` argument.
sero_timeofmalaria_district_edulevel

ggsave(
"./02_output/plots/plot15_sero_timeofmalaria_district_edulevel.png",
sero_timeofmalaria_district_edulevel,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with Fever Month
By 4 malaria
ffi_fever_month <- ffi_total %>%
drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
pivot_longer(
cols = pf_recent:pv_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "pf_recent" ~ "Recent P. Falciparum",
malaria == "pf_historic" ~ "Historical P. Falciparum",
malaria == "pv_recent" ~ "Recent P. Vivax",
malaria == "pv_historic" ~ "Historical P. Vivax"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_fever_month, age_cat, malaria) %>%
summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_4malaria_fever_month <- ffi_fever_month %>%
ggplot(
aes(
x = result_malaria,
y = age_cat,
group = age_cat
)
) +
geom_path(
color = "#bdbdbd"
) +
geom_point(
aes(color = malaria),
size = 3
) +
facet_wrap(vars(ffi_is_fever_month)) +
scale_x_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.5)
) +
labs(
y = "Age",
x = "Seropositivity",
title = str_wrap("Malaria seropositivity by type of exposure, plasmodium and presence of fever in the last month", 100)
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
ggsave(
"./02_output/plots/plot16_sero_4malaria_fevermonth.png",
sero_4malaria_fever_month,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
ffi_fever_month_typeofmalaria <- ffi_total %>%
drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
pivot_longer(
cols = pv_exposure:pf_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "pv_exposure" ~ "P. Vivax Exposure",
exposure == "pf_exposure" ~ "P. Falciparum Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_fever_month, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_typeofmalaria_fever_month <- ffi_fever_month_typeofmalaria %>%
ggplot(
aes(
x = result_exposure,
y = age_cat,
group = age_cat
)
) +
geom_path(
color = "#bdbdbd"
) +
geom_point(
aes(color = exposure),
size = 3
) +
facet_wrap(vars(ffi_is_fever_month)) +
scale_x_continuous(
labels = scales::percent_format(),
# limits = c(0, 0.5)
) +
labs(
y = "Age",
x = "Seropositivity",
title = str_wrap("Malaria seropositivity by type of plasmodium and presence of fever in the last month", 100)
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
ggsave(
"./02_output/plots/plot16_sero_typeofmalaria_fevermonth.png",
sero_typeofmalaria_fever_month,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
ffi_fever_month_timeofmalaria <- ffi_total %>%
drop_na(pf_recent:pv_historic, age_cat, ffi_is_fever_month) %>%
pivot_longer(
cols = recent_exposure:historical_exposure,
names_to = "exposure",
values_to = "result_exposure"
) %>%
mutate(
exposure = case_when(
exposure == "recent_exposure" ~ "Recent Exposure",
exposure == "historical_exposure" ~ "Historical Exposure"
),
result_exposure = case_when(
result_exposure == "Positive" ~ 1,
TRUE ~ 0
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_fever_month, age_cat, exposure) %>%
summarise(result_exposure = mean(result_exposure))
## `summarise()` has grouped output by 'ffi_is_fever_month', 'age_cat'. You can
## override using the `.groups` argument.
sero_timeofmalaria_fever_month <- ffi_fever_month_typeofmalaria %>%
ggplot(
aes(
x = result_exposure,
y = age_cat,
group = age_cat
)
) +
geom_path(
color = "#bdbdbd"
) +
geom_point(
aes(color = exposure),
size = 3
) +
facet_wrap(vars(ffi_is_fever_month)) +
scale_x_continuous(
labels = scales::percent_format(),
# limits = c(0, 0.5)
) +
labs(
y = "Age",
x = "Seropositivity",
title = str_wrap("Malaria seropositivity by time of plasmodium and presence of fever in the last month", 100)
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
ggsave(
"./02_output/plots/plot16_sero_timeofmalaria_fevermonth.png",
sero_timeofmalaria_fever_month,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with Antimalarial Drugs
By 4 Malaria
sero_4malaria_district_antimaldrugs <- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
ffi_is_antimal_drug_use
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_antimal_drug_use),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.50)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_4malaria_district_antimaldrugs

ggsave(
"./02_output/plots/plot19_sero_4malaria_district_antimaldrugs.png",
sero_4malaria_district_antimaldrugs,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_antimaldrugs <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
ffi_is_antimal_drug_use
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_antimal_drug_use),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.60)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_typeofmalaria_district_antimaldrugs

ggsave(
"./02_output/plots/plot20_sero_typeofmalaria_district_antimaldrugs.png",
sero_typeofmalaria_district_antimaldrugs,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_antimaldrugs <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
ffi_is_antimal_drug_use
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_antimal_drug_use),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.5)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_antimal_drug_use'. You can override using the `.groups` argument.
sero_timeofmalaria_district_antimaldrugs

ggsave(
"./02_output/plots/plot21_sero_timeofmalaria_district_antimaldrugs.png",
sero_timeofmalaria_district_antimaldrugs,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with time of someone had malaria
By general malaria
ffi_4malaria_mal_lifetime <- ffi_total %>%
drop_na(only_pv_exposure:freedom_malaria,
age_code, ffi_is_mal_lifetime) %>%
pivot_longer(
cols = only_pv_exposure:freedom_malaria,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "only_pv_exposure" ~ "Only P. vivax",
malaria == "only_pf_exposure" ~ "Only P. falciparum",
malaria == "pv_pf_exposure" ~ "P. vivax & falciparum Exposure",
malaria == "freedom_malaria" ~ "Freedom from Malaria"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_4malaria_mal_lifetime <- ffi_4malaria_mal_lifetime %>%
ggplot(
aes(
x = age_code,
y = result_malaria,
fill = malaria
)
) +
geom_area() +
scale_x_continuous(
limits = c(1, 8),
breaks = seq(1, 8, 1),
labels = c(
"[0-10)",
"[10-20)",
"[20-30)",
"[30-40)",
"[40-50)",
"[50-60)",
"[60-70)",
"[70+)"
),
expand = c(0, 0)
) +
scale_y_continuous(
labels = scales::percent_format(),
expand = c(0, 0)
) +
facet_wrap(vars(ffi_is_mal_lifetime)) +
labs(
y = "Seropositivity",
x = "Age",
title = str_wrap("Malaria seropositivity by type of exposure, plasmodium and how many times they think they have had malaria", 100)
) +
guides(
fill = guide_legend("Malaria")
) +
innovar::scale_fill_innova("npr") +
theme_bw() +
theme(
axis.text.x = element_text(
angle = 45,
vjust = 1,
hjust = 1
),
panel.spacing = unit(1, "lines")
)
sero_4malaria_mal_lifetime

ggsave(
"./02_output/plots/plot22_sero_4ofmalaria_mal_lifetime.png",
sero_4malaria_mal_lifetime,
dpi = 300,
bg = "white",
width = 11,
height = 5
)
By Recent Malaria
ffi_recentmalaria_mal_lifetime <- ffi_total %>%
drop_na(only_pv_recent:freedom_malaria_recent,
age_code, ffi_is_mal_lifetime) %>%
pivot_longer(
cols = only_pv_recent:freedom_malaria_recent,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "only_pv_recent" ~ "Only P. vivax Recent",
malaria == "only_pf_recent" ~ "Only P. falciparum Recent",
malaria == "pv_pf_recent" ~ "P. vivax & falciparum Recent",
malaria == "freedom_malaria_recent" ~ "Freedom from Malaria Recent"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_recentmalaria_mal_lifetime <- ffi_recentmalaria_mal_lifetime %>%
ggplot(
aes(
x = age_code,
y = result_malaria,
fill = malaria
)
) +
geom_area() +
scale_x_continuous(
limits = c(1, 8),
breaks = seq(1, 8, 1),
labels = c(
"[0-10)",
"[10-20)",
"[20-30)",
"[30-40)",
"[40-50)",
"[50-60)",
"[60-70)",
"[70+)"
),
expand = c(0, 0)
) +
scale_y_continuous(
labels = scales::percent_format(),
expand = c(0, 0)
) +
facet_wrap(vars(ffi_is_mal_lifetime)) +
labs(
y = "Seropositivity",
x = "Age",
title = str_wrap("Malaria seropositivity by recent exposure and how many times they think they have had malaria", 100)
) +
guides(
fill = guide_legend("Malaria")
) +
innovar::scale_fill_innova("npr") +
theme_bw() +
theme(
axis.text.x = element_text(
angle = 45,
vjust = 1,
hjust = 1
),
panel.spacing = unit(1, "lines")
)
sero_recentmalaria_mal_lifetime

ggsave(
"./02_output/plots/plot23_sero_recent_malaria_mal_lifetime.png",
sero_recentmalaria_mal_lifetime,
dpi = 300,
bg = "white",
width = 11,
height = 5
)
By Historic Malaria
ffi_historicmalaria_mal_lifetime <- ffi_total %>%
drop_na(only_pv_historic:freedom_malaria_historic,
age_code, ffi_is_mal_lifetime) %>%
pivot_longer(
cols = only_pv_historic:freedom_malaria_historic,
names_to = "malaria",
values_to = "result_malaria"
) %>%
mutate(
result_malaria = case_when(
result_malaria == "Positive" ~ 1,
TRUE ~ 0
),
malaria = case_when(
malaria == "only_pv_historic" ~ "Only P. vivax Historic",
malaria == "only_pf_historic" ~ "Only P. falciparum Historic",
malaria == "pv_pf_historic" ~ "P. vivax & falciparum Historic",
malaria == "freedom_malaria_historic" ~ "Freedom from Malaria Historic"
),
across(
c(ffi_is_community:ffi_is_health_facility_name),
str_to_title
)
) %>%
group_by(ffi_is_mal_lifetime, age_code, malaria) %>%
summarise(result_malaria = mean(result_malaria))
## `summarise()` has grouped output by 'ffi_is_mal_lifetime', 'age_code'. You can
## override using the `.groups` argument.
sero_historicmalaria_mal_lifetime <- ffi_historicmalaria_mal_lifetime %>%
ggplot(
aes(
x = age_code,
y = result_malaria,
fill = malaria
)
) +
geom_area() +
scale_x_continuous(
limits = c(1, 8),
breaks = seq(1, 8, 1),
labels = c(
"[0-10)",
"[10-20)",
"[20-30)",
"[30-40)",
"[40-50)",
"[50-60)",
"[60-70)",
"[70+)"
),
expand = c(0, 0)
) +
scale_y_continuous(
labels = scales::percent_format(),
expand = c(0, 0)
) +
facet_wrap(vars(ffi_is_mal_lifetime)) +
labs(
y = "Seropositivity",
x = "Age",
title = str_wrap("Malaria seropositivity by historic exposure and how many times they think they have had malaria", 100)
) +
guides(
fill = guide_legend("Malaria")
) +
innovar::scale_fill_innova("npr") +
theme_bw() +
theme(
axis.text.x = element_text(
angle = 45,
vjust = 1,
hjust = 1
),
panel.spacing = unit(1, "lines")
)
sero_historicmalaria_mal_lifetime

ggsave(
"./02_output/plots/plot24_sero_historic_malaria_mal_lifetime.png",
sero_historicmalaria_mal_lifetime,
dpi = 300,
bg = "white",
width = 11,
height = 5
)
Relation where someone usually bathe
By 4 Malaria
sero_4malaria_district_ussualybathe<- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
ffi_is_place_shower
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_place_shower),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.50)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_4malaria_district_ussualybathe

ggsave(
"./02_output/plots/plot25_sero_4malaria_district_ussualybathe.png",
sero_4malaria_district_ussualybathe,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_ussualybathe <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
ffi_is_place_shower
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_place_shower),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.60)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_typeofmalaria_district_ussualybathe

ggsave(
"./02_output/plots/plot26_sero_typeofmalaria_district_ussualybathe.png",
sero_typeofmalaria_district_ussualybathe,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_ussualybathe <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
ffi_is_place_shower
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_place_shower),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.5)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_place_shower'. You can override using the `.groups` argument.
sero_timeofmalaria_district_ussualybathe

ggsave(
"./02_output/plots/plot27_sero_timeofmalaria_district_ussualybathe.png",
sero_timeofmalaria_district_ussualybathe,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with those who have a mosquito net
By 4 Malaria
sero_4malaria_district_mosquitnet <- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
ffi_is_mosq_net
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_mosq_net),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.50)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_4malaria_district_mosquitnet

ggsave(
"./02_output/plots/plot28_sero_4malaria_district_mosquitnet.png",
sero_4malaria_district_mosquitnet,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_mosquitnet <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
ffi_is_mosq_net
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_mosq_net),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.60)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_typeofmalaria_district_mosquitnet

ggsave(
"./02_output/plots/plot29_sero_typeofmalaria_district_mosquitnet.png",
sero_typeofmalaria_district_mosquitnet,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_mosquitnet <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
ffi_is_mosq_net
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_mosq_net),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.5)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_mosq_net'. You can override using the `.groups` argument.
sero_timeofmalaria_district_mosquitnet

ggsave(
"./02_output/plots/plot30_sero_timeofmalaria_district_mosquitnet.png",
sero_timeofmalaria_district_mosquitnet,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Relation with those who have a trip in the last month
By 4 Malaria
sero_4malaria_district_tripmonth <- seropositivy_summarise(
ffi_total,
"4malaria",
age_cat,
ffi_is_trip_month
) %>%
ggplot(
aes(
x = age_cat,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_trip_month),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.50)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_4malaria_district_tripmonth

ggsave(
"./02_output/plots/plot31_sero_4malaria_district_tripmonth.png",
sero_4malaria_district_tripmonth,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Type of Malaria
sero_typeofmalaria_district_tripmonth <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
ffi_is_trip_month
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_trip_month),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.60)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_typeofmalaria_district_tripmonth

ggsave(
"./02_output/plots/plot32_sero_typeofmalaria_district_tripmonth.png",
sero_typeofmalaria_district_tripmonth,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_tripmonth <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
ffi_is_trip_month
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(ffi_is_trip_month),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
#limits = c(0, 0.5)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat',
## 'ffi_is_trip_month'. You can override using the `.groups` argument.
sero_timeofmalaria_district_tripmonth

ggsave(
"./02_output/plots/plot33_sero_timeofmalaria_district_tripmonth.png",
sero_timeofmalaria_district_tripmonth,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Descriptive 01_data
plot_4_2 <- ffi_total %>%
filter(ffi_is_malaria %in% c("No", "Yes")) %>%
drop_na(age_cat, pv_historic) %>%
mutate(
malaria_gender = paste(gender, ffi_is_malaria)
) %>%
count(pv_historic, age_cat, malaria_gender) %>%
mutate(Percentage = n / sum(n)) %>%
mutate(
Percentage = case_when(
str_detect(malaria_gender, "Female") ~ Percentage * -1,
TRUE ~ Percentage
)
) %>%
ggplot(aes(
y = age_cat,
x = Percentage,
fill = malaria_gender
)) +
geom_col(
position = position_stack(reverse = TRUE),
color = "black"
) +
labs(
x = "Age Group",
y = NULL,
title = "Population structure by age groups, gender and malaria transmission"
) +
facet_wrap(vars(pv_historic)) +
scale_x_continuous(
limits = c(-0.25, 0.25),
breaks = seq(-0.25, 0.25, 0.05),
labels = c(paste0(seq(25, 0, -5), "%"), paste0(seq(5, 25, 5), "%"))
) +
# innovar::scale_fill_innova("npr") +
scale_fill_discrete(
type = innovar::innova_pal("npr")(4),
limits = c("Male Yes", "Male No", "Female No", "Female Yes")
) +
guides(
fill = guide_legend("Have you ever \nhad malaria?")
) +
geom_vline(xintercept = 0, size = 1) +
theme_bw(base_size = 12) +
theme(
plot.title = element_text(
size = 14,
hjust = 0.5,
face = "bold"
),
strip.text = element_text(
size = 12,
face = "bold"
),
legend.title = element_text(
size = 12,
face = "bold"
),
plot.margin = margin(5, 15, 5, 15)
)
Descriptive 01_data
plot_4_2 <- ffi_total %>%
filter(ffi_is_malaria %in% c("No", "Yes")) %>%
drop_na(age_cat, pv_historic) %>%
mutate(
malaria_gender = paste(gender, ffi_is_malaria)
) %>%
count(pv_historic, age_cat, malaria_gender) %>%
mutate(Percentage = n / sum(n)) %>%
mutate(
Percentage = case_when(
str_detect(malaria_gender, "Female") ~ Percentage * -1,
TRUE ~ Percentage
)
) %>%
ggplot(aes(
y = age_cat,
x = Percentage,
fill = malaria_gender
)) +
geom_col(
position = position_stack(reverse = TRUE),
color = "black"
) +
labs(
x = "Age Group",
y = NULL,
title = "Population structure by age groups, gender and malaria transmission"
) +
facet_wrap(vars(pv_historic)) +
scale_x_continuous(
limits = c(-0.25, 0.25),
breaks = seq(-0.25, 0.25, 0.05),
labels = c(paste0(seq(25, 0, -5), "%"), paste0(seq(5, 25, 5), "%"))
) +
# innovar::scale_fill_innova("npr") +
scale_fill_discrete(
type = innovar::innova_pal("npr")(4),
limits = c("Male Yes", "Male No", "Female No", "Female Yes")
) +
guides(
fill = guide_legend("Have you ever \nhad malaria?")
) +
geom_vline(xintercept = 0, size = 1) +
theme_bw(base_size = 12) +
theme(
plot.title = element_text(
size = 14,
hjust = 0.5,
face = "bold"
),
strip.text = element_text(
size = 12,
face = "bold"
),
legend.title = element_text(
size = 12,
face = "bold"
),
plot.margin = margin(5, 15, 5, 15)
)
Sankey_seropositive
library(ggsankey)
ffi_format_sankey <- ffi_total %>%
mutate(
ffi_is_access_malaria_yn_hf = factor(
ffi_is_access_malaria_yn_hf,
label = c("No", "Yes")
),
ffi_is_mal_lifetime = as.character(ffi_is_mal_lifetime),
ffi_is_mal_lifetime = replace_na(ffi_is_mal_lifetime, "0 times"),
ffi_is_mal_lifetime = factor(
ffi_is_mal_lifetime,
labels = c(
"0 times",
"1 to 3 times",
"3 to 7 times",
"More than 7 times"
)
)
)
sankey_seropositive_answ1 <- ffi_format_sankey %>%
pivot_longer(
cols = c(recent_exposure, ffi_is_mal_lifetime, ffi_is_access_malaria_yn_hf),
names_to = "malaria_behavior1",
values_to = "malaria_answ1"
) %>%
count(malaria_behavior1, malaria_answ1) %>%
group_by(malaria_behavior1) %>%
mutate(
percentage = scales::percent(
n / sum(n),
accuracy = 0.1
)
) %>%
ungroup() %>%
mutate(
malaria_behavior1 = fct_relevel(
malaria_behavior1,
"ffi_is_mal_lifetime",
"ffi_is_access_malaria_yn_hf",
"recent_exposure"
),
malaria_percent1 = paste0(
malaria_answ1,
paste0("\n(", percentage, ")")
),
malaria_percent1 = as_factor(malaria_percent1)
) %>%
select(malaria_behavior1, malaria_answ1, malaria_percent1)
sankey_seropositive <- ffi_format_sankey %>%
drop_na(ffi_is_mal_lifetime,
ffi_is_access_malaria_yn_hf,
recent_exposure
) %>%
make_long(
ffi_is_mal_lifetime,
ffi_is_access_malaria_yn_hf,
recent_exposure
) %>%
left_join(
sankey_seropositive_answ1,
by = c(
"x" = "malaria_behavior1",
"node" = "malaria_answ1"
)
) %>%
mutate(
node = malaria_percent1,
node = fct_rev(node)
) %>%
select(-malaria_percent1) %>%
left_join(
sankey_seropositive_answ1,
by = c(
"next_x" = "malaria_behavior1",
"next_node" = "malaria_answ1"
)
) %>%
mutate(next_node = malaria_percent1) %>%
select(-malaria_percent1) %>%
ggplot(aes(
x = x,
next_x = next_x,
node = node,
next_node = next_node,
fill = factor(node),
label = node
)) +
geom_sankey(
flow.alpha = .8,
node.color = "gray30"
) +
geom_sankey_label(size = 4, color = "white", fill = "gray30") +
scale_x_discrete(
labels = str_wrap(
c(
"How many times do you think you have had malaria in your life?",
"If you had malaria, would you go to the health facility?",
"Recent exposure to any type of plasmodium"
),
30
)
) +
theme_sankey(base_size = 18) +
innovar::scale_fill_innova("npr") +
labs(
x = NULL,
title = "Behaviour associated with recent malaria exposure"
) +
theme(
legend.position = "none",
plot.title = element_text(hjust = .5),
plot.margin = margin(5, 5, 5, 5)
)
## Warning: attributes are not identical across measure variables;
## they will be dropped
ggsave("./02_output/plots/plot34_sankey_seropositive.png",
sankey_seropositive,
height = 7,
width = 14,
dpi = 300)
Relation gender and ocupation
By 4 Malaria
sero_4malaria_district_gender_economic <- seropositivy_summarise(
ffi_total,
"4malaria",
economic_activities,
gender
) %>%
ggplot(
aes(
x = economic_activities,
y = result_malaria,
color = malaria,
group = malaria
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.40)
) +
labs(
x = "Economic Activities",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw() +
theme(
axis.text.x = element_text(
angle = 45,
vjust = 1,
hjust = 1
)
)
## `summarise()` has grouped output by 'ffi_is_district', 'economic_activities',
## 'gender'. You can override using the `.groups` argument.
sero_4malaria_district_gender_economic

ggsave(
"./02_output/plots/plot35_sero_4malaria_district_gender_economic.png",
sero_4malaria_district_gender_economic,
dpi = 300,
bg = "white",
width = 11,
height = 7.5,
scale = 0.9
)
By Type of Malaria
sero_typeofmalaria_district_gender <- seropositivy_summarise(
ffi_total,
"typeofmalaria",
age_cat,
gender
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_typeofmalaria_district_gender

ggsave(
"./02_output/plots/plot11_sero_typeofmalaria_district_gender.png",
sero_typeofmalaria_district_gender,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
By Time of Malaria
sero_timeofmalaria_district_gender <- seropositivy_summarise(
ffi_total,
"timeofmalaria",
age_cat,
gender
) %>%
ggplot(
aes(
x = age_cat,
y = result_exposure,
color = exposure,
group = exposure
)
) +
geom_point() +
geom_line() +
facet_grid(
vars(gender),
vars(ffi_is_district)
) +
scale_y_continuous(
labels = scales::percent_format(),
limits = c(0, 0.45)
) +
labs(
x = "Age",
y = "Seropositivity"
) +
guides(
color = guide_legend("Malaria")
) +
innovar::scale_color_innova("npr") +
theme_bw()
## `summarise()` has grouped output by 'ffi_is_district', 'age_cat', 'gender'. You
## can override using the `.groups` argument.
sero_timeofmalaria_district_gender

ggsave(
"./02_output/plots/plot12_sero_timeofmalaria_district_gender.png",
sero_timeofmalaria_district_gender,
dpi = 300,
bg = "white",
width = 12,
height = 8.5
)
Maps
library(sf)
library(leaflet)
ffi_total_gps <- ffi_total %>%
select(
ffi_is_cod_com:ffi_is_cod_ind,
pf_recent:pv_historic,
pv_exposure:historical_exposure
) %>%
left_join(
ffi_household %>%
select(
ffi_h_code_community:ffi_h_code_household,
ffi_h_community
),
by = c(
"ffi_is_cod_com" = "ffi_h_code_community",
"ffi_is_cod_household" = "ffi_h_code_household"
)
)
ffi_household_gps <- ffi_total_gps %>%
select(
ffi_is_cod_com:ffi_is_cod_household,
ffi_h_community,
recent_exposure
) %>%
mutate(
recent_exposure = case_when(
recent_exposure == "Positive" ~ 1,
TRUE ~ 0
)
) %>%
group_by(
across(c(ffi_is_cod_com:ffi_h_community))
) %>%
summarise(
recent_exposure = mean(recent_exposure)
) %>%
ungroup()
## `summarise()` has grouped output by 'ffi_is_cod_com', 'ffi_is_cod_household'.
## You can override using the `.groups` argument.
# mutate(
# color_marker = case_when(
# recent_exposure == 0 ~ "red",
# TRUE ~ "black"
# )
# )
ffi_household_gps <- ffi_household_gps %>%
left_join(
ffi_household %>%
select(
ffi_h_code_community:ffi_h_code_household,
ffi_h_district,
ffi_gps_long,
ffi_gps_lat
),
by = c(
"ffi_is_cod_com" = "ffi_h_code_community",
"ffi_is_cod_household" = "ffi_h_code_household"
)
) %>%
mutate(
ffi_h_household_id = paste0(ffi_is_cod_com, ffi_is_cod_household),
ffi_is_cod_com_label = paste0(
"Cod: ",
ffi_is_cod_household,
" - ",
str_to_title(ffi_h_community),
" (",
str_to_title(ffi_h_district),
")"
)
) %>%
st_as_sf(
coords = c("ffi_gps_long", "ffi_gps_lat"),
crs = 4326
)
# colors_pal <- rev(innovar:::innova_palettes[["ecomst"]])
# pal <- colorNumeric(
# colorRamp(colors_pal),
# ffi_household_gps$recent_exposure
# )
pal <- colorNumeric(
hcl.colors(17, palette = "zissou"),
ffi_household_gps$recent_exposure
)
# icons_household <- awesomeIcons(
# icon = "ios-home",
# iconColor = "black",
# library = "ion",
# markerColor = innovar::innova_pal("ecomst", reverse = TRUE)(17)
# )
communities_sf <- communities_sf %>%
mutate(
ffi_h_community = str_to_title(ffi_h_community)
) %>%
left_join(
ffi_household %>%
select(ffi_h_district, ffi_h_code_community) %>%
distinct()
) %>%
mutate(
ffi_h_community_label = paste0(
ffi_h_community,
" (",
str_to_title(ffi_h_district),
")"
)
)
## Joining, by = c("ffi_h_district", "ffi_h_code_community")
household_communities_leaft <- ffi_household_gps %>%
leaflet() %>%
addProviderTiles(
providers$OpenStreetMap,
group = "OpenStreetMap"
) %>%
addCircleMarkers(
layerId = ~ffi_h_household_id,
label = ~ffi_is_cod_com_label,
color = ~ pal(recent_exposure),
group = "Households",
radius = 7,
weight = 5,
opacity = 1,
fillOpacity = 0.1,
labelOptions = labelOptions(
style = list(
"font-weight" = "bold",
padding = "3px 8px"
),
textsize = "12px",
direction = "auto"
)
) %>%
# addLegend(
# title = "Recent Exposure",
# pal = pal,
# values = ~ recent_exposure,
# group = "circles",
# position = "bottomleft",
# transform = ~ scales::percent_format(),
# opacity = 1
# ) %>%<font-awesome-icon icon="fa-solid fa-location-dot" />
leaflegend::addLegendNumeric(
title = "Recent Exposure",
pal = pal,
values = ~ recent_exposure,
position = "bottomright",
orientation = "horizontal",
height = 20,
width = 100,
decreasing = FALSE,
numberFormat = scales::percent_format(),
group = "circles"
) %>%
addAwesomeMarkers(
data = communities_sf,
layerId = ~ffi_h_code_community,
label = ~ffi_h_community_label,
group = "Communities"
) %>%
addProviderTiles(
providers$OpenStreetMap,
group = "OpenStreetMap"
) %>%
addTiles(
urlTemplate = "http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga",
attribution = "Google Maps",
options = leaflet::tileOptions(
maxNativeZoom = 19,
maxZoom = 20
),
group = "Google Maps"
) %>%
addTiles(
urlTemplate = "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
attribution = "Satellite View",
options = leaflet::tileOptions(
maxNativeZoom = 19,
maxZoom = 20
),
group = "Satellite View"
) %>%
# Layers control*
addLayersControl(
overlayGroups = c("Households", "Communities"),
baseGroups = c("OpenStreetMap", "Google Maps", "Satellite View"),
options = layersControlOptions(collapsed = FALSE)
) %>%
# addLegend(
# "topright",
# pal = innovar::innova_pal("ecomst", reverse = TRUE)(980)
# ) %>%
# addLegend(
# position = "bottomright",
# colors = c(
# "white; width:15px; height:15px;
# border:5px solid red; border-radius:50%;",
# "white; width:7.5px; height:7.5px; margin-top: 5px;
# border:5px solid black; border-radius:50%; margin-left:2px;"
# ),
# labels = c(
# "<div style='display: inline-block; height: 10px;
# margin-top: 8px;line-height: 10px;font-weight: bold;
# color: black; '>At least 1 person with recent malaria</div>",
# "<div style='display: inline-block;height: 10px;
# margin-top: 8px;line-height: 10px;font-weight: bold;
# color: black; margin-top: 10px;
# margin-left:5px'>No one with recent malaria at household</div>"
# ),
# opacity = 1
# ) %>%
leaflet.extras::addResetMapButton()
htmlwidgets::saveWidget(
household_communities_leaft,
file = "./02_output/plots/household_communities_leaft.html"
)
webshot::webshot(
"./02_output/plots/household_communities_leaft.html",
"./02_output/plots/household_communities_leaft.png",
cliprect = "viewport",
zoom = 4
)
LS0tCnRpdGxlOiAiRGVzY3JpcHRpdmUgYW5hbHlzaXMiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBybWRmb3JtYXRzOjpkb3duY3V0ZToKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICBoaWdobGlnaHQ6IGthdGUKICAgIHRvY19kZXB0aDogMwogICAgZGVmYXVsdF9zdHlsZTogZGFyawogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBoaWdobGlnaHRfZG93bmxpdDogdHJ1ZQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyMgR2xvYmFsIG9wdGlvbnMKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNhY2hlID0gVFJVRSwKICB3YXJuaW5ncyA9IEZBTFNFLAogIG1lc3NhZ2VzID0gRkFMU0UKKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCmxpYnJhcnkoZ2dzZmxhYmVsKQpgYGAKCiMgSW1wb3J0IGRhdGEKCmBgYHtyfQpzZXJvbG9neSA8LSByZWFkX2NzdigiLi8wMV9kYXRhL3Jhdy9GRkkucGVydS5zZXJvbG9neS5rbWVhbnMyLmNzdiIpICU+JQogIHJlbmFtZShmZmlfaXNfY29kZSA9IENvZGlnbykgJT4lCiAgc2VsZWN0KC0xKQoKZmZpX2luZGl2aWR1YWwgPC0gcmVhZF9jc3YoIi4vMDFfZGF0YS9yYXcvaW5kaXZpZHVhbHNfcmVzdWx0X3NoYXJlXzA3MjAyMi5jc3YiKQpmZmlfaG91c2Vob2xkIDwtIHJlYWRfY3N2KCIuLzAxX2RhdGEvcmF3L2hvdXNlaG9sZF9ncHNfc2hhcmVfMDcyMDIyLmNzdiIpCmRhdGFfMjAwMF8yMDE5IDwtIHJlYWRfY3N2KCIuLzAxX2RhdGEvcmF3L0RhdGFfRkZJXzIwMDBfMjAxOV8yMDIxMjQwNS5jc3YiKQpkYXRhXzIwMjBfMjAyMSA8LSByZWFkX2NzdigiLi8wMV9kYXRhL3Jhdy9EYXRhX0ZGSV8yMDIwXzIwMjFfMjAyMTA2MjkuY3N2IikKcG9ibGFjaW9uIDwtIHJlYWRSRFMoIi4vMDFfZGF0YS9yYXcvcG9ibGFjaW9uX2luZWlfMjAxNy5yZHMiKQpgYGAKCiMgRm9ybWF0IGRhdGEKCmBgYHtyfQpmZmlfdG90YWwgPC0gZmZpX2luZGl2aWR1YWwgJT4lCiAgZnVsbF9qb2luKAogICAgc2Vyb2xvZ3kgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICBmZmlfaXNfY29kZSA9IHBhc3RlMCgwLCBmZmlfaXNfY29kZSkKICAgICAgKSwKICAgIGJ5ID0gImZmaV9pc19jb2RlIgogICkKCmZmaV90b3RhbCA8LSBmZmlfdG90YWwgJT4lCiAgbXV0YXRlKAogICAgYWdlX2NhdCA9IGNhc2Vfd2hlbigKICAgICAgZmZpX2lzX2FnZV9maXhlZCA+PSA3MCB+ICJbNzArKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNjAgfiAiWzYwLTcwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNTAgfiAiWzUwLTYwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gNDAgfiAiWzQwLTUwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMzAgfiAiWzMwLTQwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMjAgfiAiWzIwLTMwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMTAgfiAiWzEwLTIwKSIsCiAgICAgIGZmaV9pc19hZ2VfZml4ZWQgPj0gMCB+ICJbMC0xMCkiCiAgICApLAogICAgYWdlX2NhdCA9IGZhY3RvcihhZ2VfY2F0KSwKICAgIGFnZV9jb2RlID0gY2FzZV93aGVuKAogICAgICBhZ2VfY2F0ID09ICJbNzArKSIgfiA4LAogICAgICBhZ2VfY2F0ID09ICJbNjAtNzApIiB+IDcsCiAgICAgIGFnZV9jYXQgPT0gIls1MC02MCkiIH4gNiwKICAgICAgYWdlX2NhdCA9PSAiWzQwLTUwKSIgfiA1LAogICAgICBhZ2VfY2F0ID09ICJbMzAtNDApIiB+IDQsCiAgICAgIGFnZV9jYXQgPT0gIlsyMC0zMCkiIH4gMywKICAgICAgYWdlX2NhdCA9PSAiWzEwLTIwKSIgfiAyLAogICAgICBhZ2VfY2F0ID09ICJbMC0xMCkiIH4gMSwKICAgICksCiAgICBnZW5kZXIgPSBmYWN0b3IoCiAgICAgIGZmaV9pc19zZXgsCiAgICAgIGxhYmVscyA9IGMoIk1hbGUiLCAiRmVtYWxlIikKICAgICksCiAgICBmZmlfaXNfbWFsYXJpYSA9IGZhY3RvcigKICAgICAgZmZpX2lzX21hbGFyaWEsCiAgICAgIGxhYmVscyA9IGMoIk5vIiwgIlllcyIsICJEb24ndCBLbm93IC8gTm8gQW5zd2VyIikKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMocGZfcmVjZW50OnB2X2hpc3RvcmljKSwKICAgICAgfiBmYWN0b3IoLiwgbGFiZWxzID0gYygiTmVnYXRpdmUiLCAiUG9zaXRpdmUiKSkKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoCiAgICAgICAgZmZpX2lzX2ZldmVyX21vbnRoLAogICAgICAgIGZmaV9pc19hbnRpbWFsX2RydWdfdXNlLCAKICAgICAgICBmZmlfaXNfbW9zcV9uZXQKICAgICAgKSwKICAgICAgfiBmYWN0b3IoLiwgbGFiZWxzID0gYygiTm8iLCAiWWVzIikpCiAgICApLAogICAgZmZpX2lzX3RyaXBfbW9udGggPSBmYWN0b3IoCiAgICAgIGZmaV9pc190cmlwX21vbnRoLAogICAgICBsYWJlbHMgPSBjKCJObyIsICJZZXMiLCAiRG9uJ3QgS25vdy9ObyBBbnN3ZXIiKQogICAgKSwKICAgIGZmaV9pc19tYWxfbGlmZXRpbWUgPSBmYWN0b3IoCiAgICAgIGZmaV9pc19tYWxfbGlmZXRpbWUsCiAgICAgIGxhYmVscyA9IGMoCiAgICAgICAgIjEgdG8gMyB0aW1lcyIsCiAgICAgICAgIjMgdG8gNyB0aW1lcyIsCiAgICAgICAgIk1vcmUgdGhhbiA3IHRpbWVzIgogICAgICApCiAgICApLAogICAgZmZpX2lzX3BsYWNlX3Nob3dlciA9IGZhY3RvcigKICAgICAgZmZpX2lzX3BsYWNlX3Nob3dlciwKICAgICAgbGFiZWxzID0gYygKICAgICAgICAiQmF0aHJvb20gaW5zaWRlIHRoZSBkd2VsbGluZyIsCiAgICAgICAgIkJhdGhyb29tIG91dHNpZGUgdGhlIGR3ZWxsaW5nIiwKICAgICAgICAiSW4gdGhlIGNvdW50cnlzaWRlL3JpdmVyIiwKICAgICAgICAiT3RoZXIiCiAgICAgICkKICAgICksCiAgICBlZHVjYXRpb25fbGV2ZWwgPSBjYXNlX3doZW4oCiAgICAgIGZmaV9pc19pbnN0X2xldmVsICVpbiUgMCB+ICJObyBzY2hvb2xpbmciLCAKICAgICAgZmZpX2lzX2luc3RfbGV2ZWwgJWluJSAxOjIgfiAiUHJpbWFyeSBzY2hvb2wiLAogICAgICBmZmlfaXNfaW5zdF9sZXZlbCAlaW4lIDM6NCB+ICJTZWNvbmRhcnkgc2Nob29sIiwKICAgICAgZmZpX2lzX2luc3RfbGV2ZWwgJWluJSA1OjYgfiAiSGlnaGVyIGVkdWNhdGlvbiIKICAgICksCiAgICBlZHVjYXRpb25fbGV2ZWwgPSBmY3RfcmVsZXZlbChlZHVjYXRpb25fbGV2ZWwsICJObyBzY2hvb2xpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByaW1hcnkgc2Nob29sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWNvbmRhcnkgc2Nob29sIiksCiAgICBlY29ub21pY19hY3Rpdml0aWVzID0gZmFjdG9yKGZmaV9pc19tYWluX2Vjb25fYWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJEYXkgbGFib3VyZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXb29kIGV4dHJhY3RvciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZpc2hlcm1hbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpdmVzdG9jayBmYXJtZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYXJtZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFkZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb3VzZXdpZmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHVkZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW90b3JjeWNsZSB0YXhpIGRyaXZlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIpKSwKICAgIHB2X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiAmIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiTmVnYXRpdmUiLAogICAgICBpcy5uYShwdl9yZWNlbnQpICYgaXMubmEocHZfaGlzdG9yaWMpIH4gTkFfY2hhcmFjdGVyXywKICAgICAgVFJVRSB+ICJQb3NpdGl2ZSIKICAgICksCiAgICBwZl9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgcGZfcmVjZW50ID09ICJOZWdhdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocGZfcmVjZW50KSAmIGlzLm5hKHBmX2hpc3RvcmljKSB+IE5BX2NoYXJhY3Rlcl8sCiAgICAgIFRSVUUgfiAiUG9zaXRpdmUiCiAgICApLAogICAgcmVjZW50X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiAmIHBmX3JlY2VudCA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocHZfcmVjZW50KSAmIGlzLm5hKHBmX3JlY2VudCkgfiBOQV9jaGFyYWN0ZXJfLAogICAgICBUUlVFIH4gIlBvc2l0aXZlIgogICAgKSwKICAgIGhpc3RvcmljYWxfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIk5lZ2F0aXZlIiwKICAgICAgaXMubmEocHZfaGlzdG9yaWMpICYgaXMubmEocGZfaGlzdG9yaWMpIH4gTkFfY2hhcmFjdGVyXywKICAgICAgVFJVRSB+ICJQb3NpdGl2ZSIKICAgICksCiAgICBvbmx5X3B2X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBwdl9leHBvc3VyZSA9PSAiUG9zaXRpdmUiICYgcGZfZXhwb3N1cmUgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIG9ubHlfcGZfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHBmX2V4cG9zdXJlID09ICJQb3NpdGl2ZSIgJiBwdl9leHBvc3VyZSA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgcHZfcGZfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHB2X2V4cG9zdXJlID09ICJQb3NpdGl2ZSIgJiBwZl9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gIlBvc2l0aXZlIiwKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBmcmVlZG9tX21hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIHB2X2V4cG9zdXJlID09ICJOZWdhdGl2ZSIgJiBwZl9leHBvc3VyZSA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgb25seV9wdl9yZWNlbnQgPSBjYXNlX3doZW4oCiAgICAgIHB2X3JlY2VudCA9PSAiUG9zaXRpdmUiICYgcGZfcmVjZW50ID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBvbmx5X3BmX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcGZfcmVjZW50ID09ICJQb3NpdGl2ZSIgJiBwdl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIHB2X3BmX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcHZfcmVjZW50ID09ICJQb3NpdGl2ZSIgJiBwZl9yZWNlbnQgPT0gIlBvc2l0aXZlIiB+ICJQb3NpdGl2ZSIsCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgZnJlZWRvbV9tYWxhcmlhX3JlY2VudCA9IGNhc2Vfd2hlbigKICAgICAgcHZfcmVjZW50ID09ICJOZWdhdGl2ZSIgJiBwZl9yZWNlbnQgPT0gIk5lZ2F0aXZlIiB+ICJQb3NpdGl2ZSIsIAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIG9ubHlfcHZfaGlzdG9yaWMgPSBjYXNlX3doZW4oCiAgICAgIHB2X2hpc3RvcmljID09ICJQb3NpdGl2ZSIgJiBwZl9oaXN0b3JpYyA9PSAiTmVnYXRpdmUiIH4gIlBvc2l0aXZlIiwgCiAgICAgIFRSVUUgfiAiTmVnYXRpdmUiCiAgICApLAogICAgb25seV9wZl9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcGZfaGlzdG9yaWMgPT0gIlBvc2l0aXZlIiAmIHB2X2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBwdl9wZl9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcHZfaGlzdG9yaWMgPT0gIlBvc2l0aXZlIiAmIHBmX2hpc3RvcmljID09ICJQb3NpdGl2ZSIgfiAiUG9zaXRpdmUiLAogICAgICBUUlVFIH4gIk5lZ2F0aXZlIgogICAgKSwKICAgIGZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYyA9IGNhc2Vfd2hlbigKICAgICAgcHZfaGlzdG9yaWMgPT0gIk5lZ2F0aXZlIiAmIHBmX2hpc3RvcmljID09ICJOZWdhdGl2ZSIgfiAiUG9zaXRpdmUiLCAKICAgICAgVFJVRSB+ICJOZWdhdGl2ZSIKICAgICksCiAgICBhY3Jvc3MoYyhwdl9leHBvc3VyZTpmcmVlZG9tX21hbGFyaWFfaGlzdG9yaWMpLCBmYWN0b3IpCiAgKQoKbGFiZWxsZWQ6OnZhcl9sYWJlbChmZmlfdG90YWwpIDwtIGxpc3QoCiAgZmZpX2lzX2Rpc3RyaWN0ID0gIkRpc3RyaWNzIiwKICBnZW5kZXIgPSAiR2VuZGVyIiwKICBhZ2VfY2F0ID0gIkFnZSIsCiAgZWR1Y2F0aW9uX2xldmVsID0gIkVkdWNhdGlvbiBMZXZlbCIsCiAgZWNvbm9taWNfYWN0aXZpdGllcyA9ICJFY29ub21pYyBBY3Rpdml0aWVzIiwKICBwZl9yZWNlbnQgPSAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogIHBmX2hpc3RvcmljID0gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgcHZfcmVjZW50ID0gIlJlY2VudCBQLiBWaXZheCIsCiAgcHZfaGlzdG9yaWMgPSAiSGlzdG9yaWNhbCBQLiBWaXZheCIsCiAgcHZfZXhwb3N1cmUgPSAiUC4gVml2YXggRXhwb3N1cmUiLAogIHBmX2V4cG9zdXJlID0gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCikKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CnNhdmVSRFMoZmZpX3RvdGFsLCAKICAgICAgICBmaWxlID0gIjAxX2RhdGEvcHJvY2Vzc2VkL2ZmaV90b3RhbC5yZHMiKQpgYGAKCiMgVGFibGUgZGVzY3JpcHRpdmUKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKCmZpc2hlci50ZXN0LnNpbXVsYXRlLnAudmFsdWVzIDwtIGZ1bmN0aW9uKGRhdGEsIHZhcmlhYmxlLCBieSwgLi4uKSB7CiAgcmVzdWx0IDwtIGxpc3QoKQogIHRlc3RfcmVzdWx0cyA8LSBzdGF0czo6ZmlzaGVyLnRlc3QoZGF0YVtbdmFyaWFibGVdXSwgZGF0YVtbYnldXSwgc2ltdWxhdGUucC52YWx1ZSA9IFRSVUUpCiAgcmVzdWx0JHAgPC0gdGVzdF9yZXN1bHRzJHAudmFsdWUKICByZXN1bHQkdGVzdCA8LSB0ZXN0X3Jlc3VsdHMkbWV0aG9kCiAgcmVzdWx0Cn0KYGBgCgojIyBUYWJsZSBmb3IgZGlzdHJpY3QKCmBgYHtyfQp0YWJsZV8xIDwtIGZmaV90b3RhbCAlPiUKICBzZWxlY3QoCiAgICBmZmlfaXNfZGlzdHJpY3QsCiAgICBnZW5kZXIsCiAgICBhZ2VfY2F0LAogICAgZWR1Y2F0aW9uX2xldmVsLAogICAgZWNvbm9taWNfYWN0aXZpdGllcywKICAgIHBmX3JlY2VudDpwdl9oaXN0b3JpYwogICkgJT4lCiAgdGJsX3N1bW1hcnkoCiAgICBieSA9ICJmZmlfaXNfZGlzdHJpY3QiLAogICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgKSAlPiUKICBhZGRfbigpICU+JQogIGFkZF9vdmVyYWxsKCkgJT4lCiAgYWRkX3AoCiAgICAgdGVzdCA9IGxpc3QoYWxsX2NhdGVnb3JpY2FsKCkgfiAiZmlzaGVyLnRlc3Quc2ltdWxhdGUucC52YWx1ZXMiKQogICkgJT4lIAogIGJvbGRfcCgpICU+JQogIG1vZGlmeV9oZWFkZXIobGFiZWwgPSAiKipWYXJpYWJsZSoqIikgJT4lCiAgYm9sZF9sYWJlbHMoKQogIAp0YWJsZTEKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQp0YWJsZV8xICU+JQogIGFzX2ZsZXhfdGFibGUoKSAlPiUKICBmbGV4dGFibGU6OnNhdmVfYXNfZG9jeChwYXRoID0gIi4vMDJfb3V0cHV0L3JlcG9ydHMvdGFibGUxLmRvY3giKQpgYGAKCiMjIFRhYmxlIGZvciBQbGFzbW9kaXVtCmBgYHtyfQogdGFibGUyIDwtIGZmaV90b3RhbCAlPiUKICAgc2VsZWN0KAogICAgIGdlbmRlciwKICAgICBhZ2VfY2F0LAogICAgIGVkdWNhdGlvbl9sZXZlbCwKICAgICBlY29ub21pY19hY3Rpdml0aWVzLAogICAgIHBmX2V4cG9zdXJlLAogICAgIHB2X2V4cG9zdXJlCiAgICkgJT4lCiAgIGRyb3BfbmEocGZfZXhwb3N1cmUsIHB2X2V4cG9zdXJlKSAlPiUKICAgcGl2b3RfbG9uZ2VyKAogICAgIGNvbHMgPSBwdl9leHBvc3VyZTpwZl9leHBvc3VyZSwKICAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICAgdmFsdWVzX3RvID0gInJlc3VsdF9leHBvc3VyZSIKICAgKSAlPiUKICAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAicGZfZXhwb3N1cmUiIH4gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCiAgICApCiAgICkgJT4lCiAgIHRibF9zdHJhdGEoCiAgICBzdHJhdGEgPSBleHBvc3VyZSwKICAgIC50YmxfZnVuID0KICAgICAgfiAueCAlPiUKICAgICAgICAgIHRibF9zdW1tYXJ5KAogICAgICAgICAgICBieSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgICAgICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgICAgICAgICApICU+JQogICAgICAgICAgYWRkX3AoCiAgICAgICAgICAgIHRlc3QgPSBsaXN0KGFsbF9jYXRlZ29yaWNhbCgpIH4gImZpc2hlci50ZXN0LnNpbXVsYXRlLnAudmFsdWVzIikKICAgICAgICAgICkgJT4lCiAgICAgICAgICBib2xkX3AoKSAlPiUKICAgICAgICAgIG1vZGlmeV9oZWFkZXIobGFiZWwgPSAiKipWYXJpYWJsZSoqIikgJT4lCiAgICAgICAgICBib2xkX2xhYmVscygpIAogICApIAoKdGFibGUyX292ZXJhbGwgPC0gZmZpX3RvdGFsICU+JQogIHNlbGVjdCgKICAgIGdlbmRlciwKICAgIGFnZV9jYXQsCiAgICBlZHVjYXRpb25fbGV2ZWwsCiAgICBlY29ub21pY19hY3Rpdml0aWVzLAogICAgcGZfZXhwb3N1cmUsCiAgICBwdl9leHBvc3VyZQogICkgJT4lCiAgZHJvcF9uYShwZl9leHBvc3VyZSwgcHZfZXhwb3N1cmUpICU+JQogIHRibF9zdW1tYXJ5KAogICAgbWlzc2luZ190ZXh0ID0gIk1pc3NpbmciCiAgKSAlPiUKICBtb2RpZnlfaGVhZGVyKAogICAgbGFiZWwgPSAiKipWYXJpYWJsZSoqIgogICkgJT4lCiAgYm9sZF9sYWJlbHMoKSAlPiUKICBtb2RpZnlfc3Bhbm5pbmdfaGVhZGVyKHN0YXRfMCB+ICIqKk92ZXJhbGwqKiIpCgp0YWJsZTIgPC0gdGJsX21lcmdlKAogIHRibHMgPSBsaXN0KHRhYmxlMiwgdGFibGUyX292ZXJhbGwpLAogIHRhYl9zcGFubmVyID0gRkFMU0UKKQoKdGFibGUyCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KdGFibGUyICU+JQogIGFzX2ZsZXhfdGFibGUoKSAlPiUKICBmbGV4dGFibGU6OnNhdmVfYXNfZG9jeChwYXRoID0gIi4vMDJfb3V0cHV0L3JlcG9ydHMvdGFibGUyLmRvY3giKQpgYGAKCiMjIFRhYmxlIGZvciBFeHBvc3VyZSBUaW1lCgpgYGB7cn0KIHRhYmxlMyA8LSBmZmlfdG90YWwgJT4lCiAgIHNlbGVjdCgKICAgICBnZW5kZXIsCiAgICAgYWdlX2NhdCwKICAgICBlZHVjYXRpb25fbGV2ZWwsCiAgICAgZWNvbm9taWNfYWN0aXZpdGllcywKICAgICByZWNlbnRfZXhwb3N1cmUsCiAgICAgaGlzdG9yaWNhbF9leHBvc3VyZQogICApICU+JQogICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgIHBpdm90X2xvbmdlcigKICAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgICkgJT4lCiAgIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBleHBvc3VyZSA9PSAicmVjZW50X2V4cG9zdXJlIiB+ICJSZWNlbnQgRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICkKICAgKSAlPiUKICAgdGJsX3N0cmF0YSgKICAgIHN0cmF0YSA9IGV4cG9zdXJlLAogICAgLnRibF9mdW4gPQogICAgICB+IC54ICU+JQogICAgICAgICAgdGJsX3N1bW1hcnkoCiAgICAgICAgICAgIGJ5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICAgICAgICBtaXNzaW5nX3RleHQgPSAiTWlzc2luZyIKICAgICAgICAgICkgJT4lCiAgICAgICAgICBhZGRfcCgKICAgICAgICAgICAgdGVzdCA9IGxpc3QoYWxsX2NhdGVnb3JpY2FsKCkgfiAiZmlzaGVyLnRlc3Quc2ltdWxhdGUucC52YWx1ZXMiKQogICAgICAgICAgKSAlPiUKICAgICAgICAgIGJvbGRfcCgpICU+JQogICAgICAgICAgbW9kaWZ5X2hlYWRlcihsYWJlbCA9ICIqKlZhcmlhYmxlKioiKSAlPiUKICAgICAgICAgIGJvbGRfbGFiZWxzKCkgCiAgICkgCgp0YWJsZTNfb3ZlcmFsbCA8LSBmZmlfdG90YWwgJT4lCiAgc2VsZWN0KAogICAgZ2VuZGVyLAogICAgYWdlX2NhdCwKICAgIGVkdWNhdGlvbl9sZXZlbCwKICAgIGVjb25vbWljX2FjdGl2aXRpZXMsCiAgICByZWNlbnRfZXhwb3N1cmUsCiAgICBoaXN0b3JpY2FsX2V4cG9zdXJlCiAgKSAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgdGJsX3N1bW1hcnkoCiAgICBtaXNzaW5nX3RleHQgPSAiTWlzc2luZyIKICApICU+JQogIG1vZGlmeV9oZWFkZXIoCiAgICBsYWJlbCA9ICIqKlZhcmlhYmxlKioiCiAgKSAlPiUKICBib2xkX2xhYmVscygpICU+JQogIG1vZGlmeV9zcGFubmluZ19oZWFkZXIoc3RhdF8wIH4gIioqT3ZlcmFsbCoqIikKCnRhYmxlMyA8LSB0YmxfbWVyZ2UoCiAgdGJscyA9IGxpc3QodGFibGUzLCB0YWJsZTNfb3ZlcmFsbCksCiAgdGFiX3NwYW5uZXIgPSBGQUxTRQopCgp0YWJsZTMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQp0YWJsZTMgJT4lCiAgYXNfZmxleF90YWJsZSgpICU+JQogIGZsZXh0YWJsZTo6c2F2ZV9hc19kb2N4KHBhdGggPSAiLi8wMl9vdXRwdXQvcmVwb3J0cy90YWJsZTMuZG9jeCIpCmBgYAoKCiMgRGlzdGFuY2UgY29tbXVuaXRpZXMgYW5kIHJlZ2lvbmFsIEhvc3BpdGFsCgpgYGB7cn0KaXF1aXRvc19jZW50cm8gPC0gdGliYmxlKAogICJmZmlfaF9oZWFsdGhfZmFjaWxpdHlfbmFtZSIgPSAiSG9zcGl0YWwgUmVnaW9uYWwgZGUgTG9yZXRvIiwKICBMb25naXR1ZGUgPSAtNzMuMjUzODU5MDIwODA5MDYsCiAgTGF0aXR1ZGUgPSAtMy43MjY0MDYwMTY0MTQ4NzE2LAopICU+JQogIHN0X2FzX3NmKGNvb3JkcyA9IGMoIkxvbmdpdHVkZSIsICJMYXRpdHVkZSIpLCBjcnMgPSA0MzI2KSAlPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gMzI3MTgpCgpjb21tdW5pdGllc19zZiA8LSBmZmlfaG91c2Vob2xkICU+JQogIHNlbGVjdCgKICAgIGZmaV9oX2Rpc3RyaWN0LAogICAgZmZpX2hfY29kZV9jb21tdW5pdHksCiAgICBmZmlfaF9jb21tdW5pdHksCiAgICBmZmlfZ3BzX2xvbmcsCiAgICBmZmlfZ3BzX2xhdAogICkgJT4lCiAgc3RfYXNfc2YoCiAgICBjb29yZHMgPSBjKCJmZmlfZ3BzX2xvbmciLCAiZmZpX2dwc19sYXQiKSwKICAgIGNycyA9IDQzMjYKICApICU+JQogIGdyb3VwX2J5KGZmaV9oX2Rpc3RyaWN0LCBmZmlfaF9jb2RlX2NvbW11bml0eSwgZmZpX2hfY29tbXVuaXR5KSAlPiUKICBzdW1tYXJpc2UoKSAlPiUKICBzdF9jZW50cm9pZCgpCiAgCgpjb21tdW5pdGllc19kaXN0YW5jZXMgPC0gY29tbXVuaXRpZXNfc2YgJT4lCiAgc3RfdHJhbnNmb3JtKGNycyA9IDMyNzE4KSAlPiUKICBzdF9kaXN0YW5jZShpcXVpdG9zX2NlbnRybykKCmNvbW11bml0aWVzX2Rpc3RhbmNlcyA8LSBlbmZyYW1lKGNvbW11bml0aWVzX2Rpc3RhbmNlcykgJT4lCiAgbXV0YXRlKAogICAgZmZpX2lzX2NvZF9jb20gPSBjb21tdW5pdGllc19zZiRmZmlfaF9jb2RlX2NvbW11bml0eSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBjb21tdW5pdGllc19zZiRmZmlfaF9jb21tdW5pdHksCiAgICBkaXN0YW5jZSA9IGFzLm51bWVyaWModmFsdWUpCiAgKSAlPiUKICBzZWxlY3QoLWMobmFtZSwgdmFsdWUpKQpgYGAKCkxhcyBDb211bmlkYWRlcyBtYXMgY2VyY2FuYXMgeSBtYXMgbGVqYW5hcyBwb3IgZGlzdHJpdG86CgpgYGB7ciBldmFsPUZBTFNFfQpjb21tdW5pdGllc19kaXN0YW5jZXMgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfZGlzdHJpY3QgPSBjb21tdW5pdGllc19zZiRmZmlfaF9kaXN0cmljdAogICkgJT4lCiAgZ3JvdXBfYnkoZmZpX2hfZGlzdHJpY3QpICU+JQogIHNsaWNlX21pbihkaXN0YW5jZSwgbiA9IDEpICU+JQogIGJpbmRfcm93cygKICAgIGNvbW11bml0aWVzX2Rpc3RhbmNlcyAlPiUKICAgICAgbXV0YXRlKAogICAgICAgIGZmaV9oX2Rpc3RyaWN0ID0gY29tbXVuaXRpZXNfc2YkZmZpX2hfZGlzdHJpY3QKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2hfZGlzdHJpY3QpICU+JQogICAgICBzbGljZV9tYXgoZGlzdGFuY2UsIG4gPSAxKQogICkgJT4lCiAgYXJyYW5nZShmZmlfaF9kaXN0cmljdCwgZGlzdGFuY2UpCmBgYAoKIyBQbG90cwoKIyMgTWFsYXJpYSBBbm51YWwgUGFyYXNpdGUgSW5kZXgKCgpgYGB7cn0KZGF0YV9tYWxhcmlhIDwtIGJpbmRfcm93cygKICBkYXRhXzIwMDBfMjAxOSwKICBkYXRhXzIwMjBfMjAyMQopICU+JQogIGRyb3BfbmEoRGlzdHJpY3QpCgpwb2JfbG9yZXRvIDwtIHBvYmxhY2lvbiAlPiUKICBmaWx0ZXIoZGVwID09ICJMT1JFVE8iKSAlPiUKICBzZWxlY3QoRGlzdHJpY3QgPSBkaXN0ciwgVG90YWwpCmBgYAoKCmBgYHtyfQptYWxhcmlhX2Nhc2VzX3BvYiA8LSBkYXRhX21hbGFyaWEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZSgKICAgIGNhc2VzX21hbGFyaWEgPSBzdW0oCiAgICAgIGNfYWNyb3NzKGMoCiAgICAgICAgYENvbmZpcm1lZCBQLiBGYWxjaXBhcnVtYCwKICAgICAgICBgQ29uZmlybWVkIFAuIFZpdmF4YAogICAgICApKSwKICAgICAgbmEucm0gPSBUUlVFCiAgICApCiAgKSAlPiUKICBncm91cF9ieShEaXN0cmljdCkgJT4lCiAgc3VtbWFyaXNlKGNhc2VzX21hbGFyaWEgPSBzdW0oY2FzZXNfbWFsYXJpYSkpCgptYWxhcmlhX2Nhc2VzX3BvYiA8LSBtYWxhcmlhX2Nhc2VzX3BvYiAlPiUKICBsZWZ0X2pvaW4oCiAgICBwb2JfbG9yZXRvCiAgKSAlPiUKICBtdXRhdGUoCiAgICBhcGkgPSBjYXNlc19tYWxhcmlhICogMTAwMCAvIFRvdGFsCiAgKQoKZGF0YShQZXJ1LCBwYWNrYWdlID0gImlubm92YXIiKQoKbWFsYXJpYV9jYXNlc19wb2Jfc2YgPC0gUGVydSAlPiUKICBmaWx0ZXIoZGVwID09ICJMT1JFVE8iKSAlPiUKICBzZWxlY3QoRGlzdHJpY3QgPSBkaXN0ciwgZ2VvbWV0cnkpICU+JSAKICByaWdodF9qb2luKAogICAgbWFsYXJpYV9jYXNlc19wb2IKICApCmBgYAoKCmBgYHtyfQpmaWd1cmUxIDwtIGdncGxvdChtYWxhcmlhX2Nhc2VzX3BvYl9zZikgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBhcGksIGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgZ2VvbV9zZihkYXRhID0gbWFsYXJpYV9jYXNlc19wb2Jfc2YgJT4lIGRwbHlyOjpmaWx0ZXIoRGlzdHJpY3QgPT0gIkJFTEVOIiksIGNvbG91ciA9ICIjYWE2NDM5IiwgZmlsbCA9IE5BLCBzaXplID0gMS41LCBhZXMoZmlsbCA9IGFwaSwgZ2VvbWV0cnkgPSBnZW9tZXRyeSkpICsKICBnZW9tX3NmKGRhdGEgPSBtYWxhcmlhX2Nhc2VzX3BvYl9zZiAlPiUgZHBseXI6OmZpbHRlcihEaXN0cmljdCA9PSAiSU5ESUFOQSIpLCBjb2xvdXIgPSAiIzI1NmU1ZCIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEuNSwgYWVzKGZpbGwgPSBhcGksIGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoCiAgICBuYW1lID0gIkFQSSIsCiAgICBuYS52YWx1ZSA9ICJibGFjayIsCiAgICAjIGxpbWl0cyA9IGMoMCwgNDAwMCksCiAgICBwYWxldHRlID0gIlJkWWxHbiIsCiAgICBkaXJlY3Rpb24gPSAtMSwKICAgIGJyZWFrcyA9IHNjYWxlczo6cHJldHR5X2JyZWFrcyhuID0gNSksCiAgICB2YWx1ZXMgPSBjKAogICAgICAwLAogICAgICAwLjAwMSwKICAgICAgMC4wMDIsCiAgICAgIDAuMDA1LAogICAgICAwLjAwOCwKICAgICAgMC4wMSwKICAgICAgMC4wMiwKICAgICAgMC4wMywKICAgICAgMC4wNSwKICAgICAgMC4xLAogICAgICAwLjYsCiAgICAgIDAuOSwKICAgICAgMQogICAgKQogICkgKwogIGxhYnMoCiAgICB4ID0gTlVMTCwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSBOVUxMCiAgKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZW9tX3NmX2xhYmVsX3JlcGVsKAogICAgZGF0YSA9IG1hbGFyaWFfY2FzZXNfcG9iX3NmICU+JSBkcGx5cjo6ZmlsdGVyKERpc3RyaWN0ID09ICJCRUxFTiIpLAogICAgYWVzKGxhYmVsID0gRGlzdHJpY3QpLAogICAgbWluLnNlZ21lbnQubGVuZ3RoID0gMCwKICAgIGZvcmNlID0gMTAwLAogICAgbnVkZ2VfeCA9IC0xLAogICAgc2VlZCA9IDEwLAogICAgY29sb3VyID0gIiNhYTY0MzkiCiAgKSArCiAgZ2VvbV9zZl9sYWJlbF9yZXBlbCgKICAgIGRhdGEgPSBtYWxhcmlhX2Nhc2VzX3BvYl9zZiAlPiUgZHBseXI6OmZpbHRlcihEaXN0cmljdCA9PSAiSU5ESUFOQSIpLAogICAgYWVzKGxhYmVsID0gRGlzdHJpY3QpLAogICAgbWluLnNlZ21lbnQubGVuZ3RoID0gMCwKICAgIGZvcmNlID0gMTAwLAogICAgbnVkZ2VfeCA9IDEsCiAgICBzZWVkID0gMTAsCiAgICBjb2xvdXIgPSAiIzI1NmU1ZCIKICApCgpmaWd1cmUxCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9maWd1cmUxLnBuZyIsCiAgZmlndXJlMSwKICBkZXZpY2UgPSBnckRldmljZXM6OnBuZywKICBkcGkgPSAzMDAKKQpgYGAKCgojIyBTZXJvbG9naWNhbCBSZXN1bHRzCgojIyMgQnkgY29tbXVuaXRpZXMgYW5kIHR5cGUgb2YgcGxhc21vZGl1bS90aW1lCmBgYHtyfQojIGZmaV90b3RhbCAlPiUKIyAgIGdncGxvdChhZXMoCiMgICAgIHggPSBmZmlfaXNfY29tbXVuaXR5LAojICAgICBmaWxsID0gcHZfaGlzdG9yaWMKIyAgICkpICsKIyAgIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKIyAgIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKQoKcGxvdDEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljKSAlPiUKICBsZWZ0X2pvaW4oCiAgICBjb21tdW5pdGllc19kaXN0YW5jZXMKICApICAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUKICBtdXRhdGUoCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgZmZpX2lzX2NvbW11bml0eSA9IHN0cl90b190aXRsZShmZmlfaXNfY29tbXVuaXR5KSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBwYXN0ZTAoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgICIgKCIsCiAgICAgIHN0cl90b190aXRsZShmZmlfaXNfZGlzdHJpY3QpLAogICAgICAiKSIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfbWFsYXJpYQogICkpICsKICBmYWNldF93cmFwKHZhcnMobWFsYXJpYSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIiwgY29sb3IgPSAiYmxhY2siKSArCiAgY29vcmRfZmxpcCh5bGltID0gYygwLCAwLjI1KSkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKQogICkgKwogICNnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArICAKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYWNlID0gImJvbGQiLAogICAgICBzaXplID0gMTEKICAgICkKICApCgpwbG90MQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDFfdHlwZW9mbWFsYXJpYV9jb21tdW5pdGllcy5wbmciLAogIHBsb3QxLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMCwKICBoZWlnaHQgPSA5CikKYGBgCgoKIyMjIEJ5IGNvbW11bml0aWVzLCBJbmRpYW5hIGFuZCB0eXBlIG9mIHBsYXNtb2RpdW0vdGltZQpgYGB7cn0KcGxvdDFfaW5kaWFuYSA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMpICU+JQogIGxlZnRfam9pbigKICAgIGNvbW11bml0aWVzX2Rpc3RhbmNlcwogICkgICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gInBmX3JlY2VudCIgfiAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwZl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICBtYWxhcmlhID09ICJwdl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBWaXZheCIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpCiAgKSAlPiUKICBmaWx0ZXIoZmZpX2lzX2Rpc3RyaWN0ID09ICJJTkRJQU5BIikgJT4lCiAgbXV0YXRlKAogICAgZmZpX2lzX2NvbW11bml0eSA9IGZjdF9yZW9yZGVyKAogICAgICBmZmlfaXNfY29tbXVuaXR5LAogICAgICBkaXN0YW5jZSwKICAgICAgLmRlc2MgPSBUUlVFCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeCA9IGZmaV9pc19jb21tdW5pdHksCiAgICBmaWxsID0gcmVzdWx0X21hbGFyaWEKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKG1hbGFyaWEpKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKwogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICAjZ2dzY2k6OnNjYWxlX2ZpbGxfbGFuY2V0KCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHRpdGxlID0gc3RyX3dyYXAoIlNlcm9sb2dpY2FsIHJlc3VsdHMgYnkgcGxhc21vZGl1bSB0eXBlIG9mIG1hbGFyaWEgaW4gdGhlIEluZGlhbmEgRGlzdHJpY3QiLCAxMDApLAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArICAKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYWNlID0gImJvbGQiLAogICAgICBzaXplID0gMTEKICAgICkKICApCgpwbG90MV9pbmRpYW5hCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MV90eXBlb2ZtYWxhcmlhX2NvbW11bml0aWVzX2luZGlhbmEucG5nIiwKICBwbG90MV9pbmRpYW5hLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMCwKICBoZWlnaHQgPSA5CikKYGBgCgoKIyMjIEJ5IGNvbW11bml0aWVzLCBCZWxlbiBhbmQgdHlwZSBvZiBwbGFzbW9kaXVtL3RpbWUKYGBge3J9CnBsb3QxX2JlbGVuIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX3JlY2VudDpwdl9oaXN0b3JpYykgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUKICBmaWx0ZXIoZmZpX2lzX2Rpc3RyaWN0ID09ICJCRUxFTiIpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gInBmX3JlY2VudCIgfiAiUmVjZW50IFAuIEZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwZl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICBtYWxhcmlhID09ICJwdl9oaXN0b3JpYyIgfiAiSGlzdG9yaWNhbCBQLiBWaXZheCIKICAgICksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpLAogICAgZmZpX2lzX2NvbW11bml0eSA9IGZjdF9yZW9yZGVyKAogICAgICBmZmlfaXNfY29tbXVuaXR5LAogICAgICBkaXN0YW5jZSwKICAgICAgLmRlc2MgPSBUUlVFCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeCA9IGZmaV9pc19jb21tdW5pdHksCiAgICBmaWxsID0gcmVzdWx0X21hbGFyaWEKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKG1hbGFyaWEpKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKwogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMC4yNSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICAjZ2dzY2k6OnNjYWxlX2ZpbGxfbGFuY2V0KCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHRpdGxlID0gc3RyX3dyYXAoIlNlcm9sb2dpY2FsIHJlc3VsdHMgYnkgcGxhc21vZGl1bSB0eXBlIG9mIG1hbGFyaWEgaW4gdGhlIEJlbGVuIERpc3RyaWN0IiwgMTAwKSwKICAgIHggPSAiQ29tbXVuaXRpZXMiLAogICAgeSA9ICJQZXJjZW50YWdlIgogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIlJlc3VsdHMiKQogICkgKyAgCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDFfYmVsZW4KYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXNfYmVsZW4ucG5nIiwKICBwbG90MV9iZWxlbiwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKIyMjIEJ5IGNvbW11bml0aWVzLCB0eXBlIG9mIHBsYXNtb2RpdW0gZXhwb3N1cmUKYGBge3J9CnBsb3QyIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX2V4cG9zdXJlLCBwdl9leHBvc3VyZSkgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgICU+JQogIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgICBleHBvc3VyZSA9PSAicHZfZXhwb3N1cmUiIH4gIlAuIFZpdmF4IEV4cG9zdXJlIiwKICAgICAgICAgZXhwb3N1cmUgPT0gInBmX2V4cG9zdXJlIiB+ICJQLiBGYWxjaXBhcnVtIEV4cG9zdXJlIgogICAgKSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBzdHJfdG9fdGl0bGUoZmZpX2lzX2NvbW11bml0eSksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfZXhwb3N1cmUKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKGV4cG9zdXJlKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBjb2xvciA9ICJibGFjayIpICsKICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDAuNDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgIyBnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDIKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXMucG5nIiwKICBwbG90MiwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKIyMjIEJ5IGNvbW11bml0aWVzLCB0aW1lIG9mIHBsYXNtb2RpdW0gZXhwb3N1cmUKYGBge3J9CnBsb3QzIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSkgJT4lCiAgbGVmdF9qb2luKAogICAgY29tbXVuaXRpZXNfZGlzdGFuY2VzCiAgKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJyZWNlbnRfZXhwb3N1cmUiIH4gIlJlY2VudCBFeHBvc3VyZSIsCiAgICAgIGV4cG9zdXJlID09ICJoaXN0b3JpY2FsX2V4cG9zdXJlIiB+ICJIaXN0b3JpY2FsIEV4cG9zdXJlIgogICAgKSwKICAgIGZmaV9pc19jb21tdW5pdHkgPSBzdHJfdG9fdGl0bGUoZmZpX2lzX2NvbW11bml0eSksCiAgICBmZmlfaXNfY29tbXVuaXR5ID0gZmN0X3Jlb3JkZXIoCiAgICAgIGZmaV9pc19jb21tdW5pdHksCiAgICAgIGRpc3RhbmNlLAogICAgICAuZGVzYyA9IFRSVUUKICAgICkKICApICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gZmZpX2lzX2NvbW11bml0eSwKICAgIGZpbGwgPSByZXN1bHRfZXhwb3N1cmUKICApKSArCiAgZmFjZXRfd3JhcCh2YXJzKGV4cG9zdXJlKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBjb2xvciA9ICJibGFjayIpICsKICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDAuMzApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgIyBnZ3NjaTo6c2NhbGVfZmlsbF9sYW5jZXQoKSArCiAgaW5ub3Zhcjo6c2NhbGVfZmlsbF9pbm5vdmEoIm5wciIpICsKICBsYWJzKAogICAgeCA9ICJDb21tdW5pdGllcyIsCiAgICB5ID0gIlBlcmNlbnRhZ2UiCiAgKSArCiAgZ3VpZGVzKAogICAgZmlsbCA9IGd1aWRlX2xlZ2VuZCgiUmVzdWx0cyIpCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMQogICAgKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDExCiAgICApCiAgKQoKcGxvdDMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzX3R5cGVvZm1hbGFyaWFfY29tbXVuaXRpZXMucG5nIiwKICBwbG90MywKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTAsCiAgaGVpZ2h0ID0gOQopCmBgYAoKCmBgYHtyfQojIGZmaV90b3RhbCAlPiUKIyAgIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0KSAlPiUKIyAgIHBpdm90X2xvbmdlcigKIyAgICAgY29scyA9IHBmX3JlY2VudDpwdl9oaXN0b3JpYywKIyAgICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiMgICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKIyAgICkgJT4lCiMgICBtdXRhdGUoCiMgICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAojICAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAojICAgICAgIFRSVUUgfiAwCiMgICAgICksCiMgICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiMgICAgICAgbWFsYXJpYSA9PSAicGZfcmVjZW50IiB+ICJSZWNlbnQgUC4gRmFsY2lwYXJ1bSIsCiMgICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiMgICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAojICAgICAgIG1hbGFyaWEgPT0gInB2X2hpc3RvcmljIiB+ICJIaXN0b3JpY2FsIFAuIFZpdmF4IgojICAgICApLAojICAgICBmZmlfaXNfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9pc19jb21tdW5pdHkpCiMgICApICU+JQojICAgZ3JvdXBfYnkoZmZpX2lzX2NvbW11bml0eSwgYWdlX2NhdCwgbWFsYXJpYSkgJT4lCiMgICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkgJT4lCiMgICBnZ3Bsb3QoCiMgICAgIGFlcygKIyAgICAgICB4ID0gYWdlX2NhdCwKIyAgICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiMgICAgICAgY29sb3IgPSBtYWxhcmlhLAojICAgICAgIGdyb3VwID0gbWFsYXJpYQojICAgICApCiMgICApICsKIyAgIGdlb21fcG9pbnQoKSArCiMgICBnZW9tX2xpbmUoKSArCiMgICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX2NvbW11bml0eSkpICsKIyAgIHRoZW1lX2J3KCkKYGBgCgojIyBTZXJvcG9zaXRpdml0eSA0IG1hbGFyaWEKCiMjIyBCeSBkaXN0cmljdApgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdCA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIGFnZV9jYXQpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZGlzdHJpY3QsIGFnZV9jYXQsIG1hbGFyaWEpICU+JQogIHN1bW1hcmlzZShyZXN1bHRfbWFsYXJpYSA9IG1lYW4ocmVzdWx0X21hbGFyaWEpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiAgICAgIGNvbG9yID0gbWFsYXJpYSwKICAgICAgZ3JvdXAgPSBtYWxhcmlhCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19kaXN0cmljdCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNDApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fNG1hbGFyaWFfZGlzdHJpY3QKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3Q0X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3QucG5nIiwKICBzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA3LjUKKQpgYGAKCgojIyMgQnkgSGVhbHRoIEZhY2lsaXR5CgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9oZiA8LSBmZmlfdG90YWwgJT4lCiAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIGFnZV9jYXQpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApLAogICAgZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lID0gcGFzdGUoCiAgICAgIGZmaV9pc19kaXN0cmljdCwKICAgICAgZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lLAogICAgICBzZXAgPSAiIC0gIgogICAgKQogICkgJT4lCiAgZ3JvdXBfYnkoZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lLCBhZ2VfY2F0LCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKyAKICB0aGVtZV9idygpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KAogICAgICBhbmdsZSA9IDQ1LAogICAgICB2anVzdCA9IDEsCiAgICAgIGhqdXN0ID0gMQogICAgKQogICkKICAKc2Vyb180bWFsYXJpYV9oZgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDVfc2Vyb180bWFsYXJpYV9oZi5wbmciLAogIHNlcm9fNG1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEwLAogIGhlaWdodCA9IDcKKQpgYGAKCiMjIFNlb3Bvc2l0aXZpdHkgYnkgVHlwZSBvZiBNYWxhcmlhCgojIyMgQnkgRGlzdHJpY3QKCmBgYHtyfQpmZmlfdHlwZW9mX21hbGFyaWEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfZXhwb3N1cmUsIHB2X2V4cG9zdXJlLCBhZ2VfY2F0KSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgbXV0YXRlKAogICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAicGZfZXhwb3N1cmUiIH4gIlAuIEZhbGNpcGFydW0gRXhwb3N1cmUiCiAgICApLAogICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0IDwtIGZmaV90eXBlb2ZfbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfZGlzdHJpY3QsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19kaXN0cmljdCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNDApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3Q2X3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdC5wbmciLAogIHNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdCwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gNy41CikKYGBgCgojIyMgQnkgSGVhbHRoIEZhY2lsaXR5CgpgYGB7cn0Kc2Vyb190eXBlb2ZtYWxhcmlhX2hmIDwtIGZmaV90eXBlb2ZfbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2hmCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90N19zZXJvX3R5cGVvZm1hbGFyaWFfaGYucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEzLAogIGhlaWdodCA9IDkKKQpgYGAKCiMjIFNlcm9wb3NpdGl2aXR5IGJ5IFRpbWUgb2YgRXhwb3N1cmUgCgojIyMgQnkgRGlzdHJpY3QKYGBge3J9CmZmaV90aW1lb2ZtYWxhcmlhIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSwgYWdlX2NhdCkgJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IHJlY2VudF9leHBvc3VyZTpoaXN0b3JpY2FsX2V4cG9zdXJlLAogICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9leHBvc3VyZSIKICApICU+JQogIG11dGF0ZSgKICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICBleHBvc3VyZSA9PSAicmVjZW50X2V4cG9zdXJlIiB+ICJSZWNlbnQgRXhwb3N1cmUiLAogICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICksCiAgICByZXN1bHRfZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApCgpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QgPC0gZmZpX3RpbWVvZm1hbGFyaWEgJT4lCiAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCBhZ2VfY2F0LCBleHBvc3VyZSkgJT4lCiAgc3VtbWFyaXNlKHJlc3VsdF9leHBvc3VyZSA9IG1lYW4ocmVzdWx0X2V4cG9zdXJlKSkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfZGlzdHJpY3QpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgbGltaXRzID0gYygwLCAwLjQwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90OF9zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3QsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDcuNQopCmBgYAoKIyMjIEJ5IEhlYWx0aCBGYWNpbGl0eQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9oZiA8LSBmZmlfdGltZW9mbWFsYXJpYSAlPiUKICBncm91cF9ieShmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArIAogIHRoZW1lX2J3KCkKICAKc2Vyb190aW1lb2ZtYWxhcmlhX2hmCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90OV9zZXJvX3RpbWVvZm1hbGFyaWFfaGYucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfaGYsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEzLAogIGhlaWdodCA9IDkKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggc2V4CgpgYGB7cn0KbGlicmFyeShybGFuZykKCnNlcm9wb3NpdGl2eV9zdW1tYXJpc2UgPC0gZnVuY3Rpb24oZGF0YSwgdHlwZSwgdmFyaWFibGUsIC4uLikgewogIGlmICh0eXBlID09ICI0bWFsYXJpYSIpIHsKICAgIGZmaV90b3RhbCAlPiUKICAgICAgZHJvcF9uYShwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsIHt7IHZhcmlhYmxlIH19LCAuLi4pICU+JQogICAgICBwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9IHBmX3JlY2VudDpwdl9oaXN0b3JpYywKICAgICAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgICAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgICAgICkgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICByZXN1bHRfbWFsYXJpYSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAogICAgICAgICAgVFJVRSB+IDAKICAgICAgICApLAogICAgICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgICAgIG1hbGFyaWEgPT0gInBmX2hpc3RvcmljIiB+ICJIaXN0b3JpY2FsIFAuIEZhbGNpcGFydW0iLAogICAgICAgICAgbWFsYXJpYSA9PSAicHZfcmVjZW50IiB+ICJSZWNlbnQgUC4gVml2YXgiLAogICAgICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBtYWxhcmlhKSAlPiUKICAgICAgc3VtbWFyaXNlKHJlc3VsdF9tYWxhcmlhID0gbWVhbihyZXN1bHRfbWFsYXJpYSkpCiAgfSBlbHNlIGlmICh0eXBlID09ICJ0eXBlb2ZtYWxhcmlhIiApIHsKICAgIGZmaV90b3RhbCAlPiUKICAgICAgZHJvcF9uYShwZl9leHBvc3VyZSwgcHZfZXhwb3N1cmUsIHt7IHZhcmlhYmxlIH19LCAuLi4pICU+JQogICAgICBwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9IHB2X2V4cG9zdXJlOnBmX2V4cG9zdXJlLAogICAgICAgIG5hbWVzX3RvID0gImV4cG9zdXJlIiwKICAgICAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICAgICApICU+JQogICAgICBtdXRhdGUoCiAgICAgICAgZXhwb3N1cmUgPSBjYXNlX3doZW4oCiAgICAgICAgICBleHBvc3VyZSA9PSAicHZfZXhwb3N1cmUiIH4gIlAuIFZpdmF4IEV4cG9zdXJlIiwKICAgICAgICAgIGV4cG9zdXJlID09ICJwZl9leHBvc3VyZSIgfiAiUC4gRmFsY2lwYXJ1bSBFeHBvc3VyZSIKICAgICAgICApLAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICAgIFRSVUUgfiAwCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBleHBvc3VyZSkgJT4lCiAgICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpCiAgfSBlbHNlIGlmICh0eXBlID09ICJ0aW1lb2ZtYWxhcmlhIikgewogICAgZmZpX3RvdGFsICU+JQogICAgICBkcm9wX25hKHJlY2VudF9leHBvc3VyZSwgaGlzdG9yaWNhbF9leHBvc3VyZSwgCiAgICAgICAgICAgICAge3sgdmFyaWFibGUgfX0sIC4uLikgJT4lCiAgICAgIHBpdm90X2xvbmdlcigKICAgICAgICBjb2xzID0gcmVjZW50X2V4cG9zdXJlOmhpc3RvcmljYWxfZXhwb3N1cmUsCiAgICAgICAgbmFtZXNfdG8gPSAiZXhwb3N1cmUiLAogICAgICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgICAgICkgJT4lCiAgICAgIG11dGF0ZSgKICAgICAgICBleHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIGV4cG9zdXJlID09ICJyZWNlbnRfZXhwb3N1cmUiIH4gIlJlY2VudCBFeHBvc3VyZSIsCiAgICAgICAgICBleHBvc3VyZSA9PSAiaGlzdG9yaWNhbF9leHBvc3VyZSIgfiAiSGlzdG9yaWNhbCBFeHBvc3VyZSIKICAgICAgICApLAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICAgIFRSVUUgfiAwCiAgICAgICAgKSwKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgICAgIHN0cl90b190aXRsZQogICAgICAgICkKICAgICAgKSAlPiUKICAgICAgZ3JvdXBfYnkoZmZpX2lzX2Rpc3RyaWN0LCB7eyB2YXJpYWJsZSB9fSwgLi4uLCBleHBvc3VyZSkgJT4lCiAgICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpICAgICAgCiAgfSAgCn0KYGBgCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXIgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXIKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxMF9zZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlci5wbmciLAogIHNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0eXBlb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDExX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEyX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggRWR1Y2F0aW9uIExldmVsCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9lZHVsZXZlbCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9lZHVsZXZlbApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEzX3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwucG5nIiwKICBzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTRfc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZWR1bGV2ZWwgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInRpbWVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZWR1Y2F0aW9uX2xldmVsCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGVkdWNhdGlvbl9sZXZlbCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTVfc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2VkdWxldmVsLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggRmV2ZXIgTW9udGgKCiMjIyMgQnkgNCBtYWxhcmlhCmBgYHtyfQpmZmlfZmV2ZXJfbW9udGggPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0LCBmZmlfaXNfZmV2ZXJfbW9udGgpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBwZl9yZWNlbnQ6cHZfaGlzdG9yaWMsCiAgICBuYW1lc190byA9ICJtYWxhcmlhIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfbWFsYXJpYSIKICApICU+JQogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJwZl9yZWNlbnQiIH4gIlJlY2VudCBQLiBGYWxjaXBhcnVtIiwKICAgICAgbWFsYXJpYSA9PSAicGZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gRmFsY2lwYXJ1bSIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3JlY2VudCIgfiAiUmVjZW50IFAuIFZpdmF4IiwKICAgICAgbWFsYXJpYSA9PSAicHZfaGlzdG9yaWMiIH4gIkhpc3RvcmljYWwgUC4gVml2YXgiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIG1hbGFyaWEpICU+JQogIHN1bW1hcmlzZShyZXN1bHRfbWFsYXJpYSA9IG1lYW4ocmVzdWx0X21hbGFyaWEpKQoKCnNlcm9fNG1hbGFyaWFfZmV2ZXJfbW9udGggPC0gZmZpX2ZldmVyX21vbnRoICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IHJlc3VsdF9tYWxhcmlhLAogICAgICB5ID0gYWdlX2NhdCwKICAgICAgZ3JvdXAgPSBhZ2VfY2F0CiAgICApCiAgKSArCiAgZ2VvbV9wYXRoKAogICAgY29sb3IgPSAiI2JkYmRiZCIKICApICsKICBnZW9tX3BvaW50KAogICAgYWVzKGNvbG9yID0gbWFsYXJpYSksCiAgICBzaXplID0gMwogICkgKwogIGZhY2V0X3dyYXAodmFycyhmZmlfaXNfZmV2ZXJfbW9udGgpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB5ID0gIkFnZSIsCiAgICB4ID0gIlNlcm9wb3NpdGl2aXR5IiwKICAgIHRpdGxlID0gc3RyX3dyYXAoIk1hbGFyaWEgc2Vyb3Bvc2l0aXZpdHkgYnkgdHlwZSBvZiBleHBvc3VyZSwgcGxhc21vZGl1bSBhbmQgcHJlc2VuY2Ugb2YgZmV2ZXIgaW4gdGhlIGxhc3QgbW9udGgiLCAxMDApCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QxNl9zZXJvXzRtYWxhcmlhX2ZldmVybW9udGgucG5nIiwKICBzZXJvXzRtYWxhcmlhX2ZldmVyX21vbnRoLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CmZmaV9mZXZlcl9tb250aF90eXBlb2ZtYWxhcmlhIDwtIGZmaV90b3RhbCAlPiUKICBkcm9wX25hKHBmX3JlY2VudDpwdl9oaXN0b3JpYywgYWdlX2NhdCwgZmZpX2lzX2ZldmVyX21vbnRoKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gcHZfZXhwb3N1cmU6cGZfZXhwb3N1cmUsCiAgICBuYW1lc190byA9ICJleHBvc3VyZSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X2V4cG9zdXJlIgogICkgJT4lCiAgICBtdXRhdGUoCiAgICAgIGV4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgIGV4cG9zdXJlID09ICJwdl9leHBvc3VyZSIgfiAiUC4gVml2YXggRXhwb3N1cmUiLAogICAgICAgIGV4cG9zdXJlID09ICJwZl9leHBvc3VyZSIgfiAiUC4gRmFsY2lwYXJ1bSBFeHBvc3VyZSIKICAgICAgKSwKICAgICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICAgIHJlc3VsdF9leHBvc3VyZSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgICBUUlVFIH4gMAogICAgICApLAogICAgICBhY3Jvc3MoCiAgICAgICAgYyhmZmlfaXNfY29tbXVuaXR5OmZmaV9pc19oZWFsdGhfZmFjaWxpdHlfbmFtZSksCiAgICAgICAgc3RyX3RvX3RpdGxlCiAgICAgICkKICAgICkgJT4lCiAgICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICAgIHN1bW1hcmlzZShyZXN1bHRfZXhwb3N1cmUgPSBtZWFuKHJlc3VsdF9leHBvc3VyZSkpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZmV2ZXJfbW9udGggPC0gZmZpX2ZldmVyX21vbnRoX3R5cGVvZm1hbGFyaWEgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICB5ID0gYWdlX2NhdCwKICAgICAgZ3JvdXAgPSBhZ2VfY2F0CiAgICApCiAgKSArCiAgZ2VvbV9wYXRoKAogICAgY29sb3IgPSAiI2JkYmRiZCIKICApICsKICBnZW9tX3BvaW50KAogICAgYWVzKGNvbG9yID0gZXhwb3N1cmUpLAogICAgc2l6ZSA9IDMKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX2ZldmVyX21vbnRoKSkgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICMgbGltaXRzID0gYygwLCAwLjUpCiAgKSArCiAgbGFicygKICAgIHkgPSAiQWdlIiwKICAgIHggPSAiU2Vyb3Bvc2l0aXZpdHkiLAogICAgdGl0bGUgPSBzdHJfd3JhcCgiTWFsYXJpYSBzZXJvcG9zaXRpdml0eSBieSB0eXBlIG9mIHBsYXNtb2RpdW0gYW5kIHByZXNlbmNlIG9mIGZldmVyIGluIHRoZSBsYXN0IG1vbnRoIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MTZfc2Vyb190eXBlb2ZtYWxhcmlhX2ZldmVybW9udGgucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZmV2ZXJfbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCgpgYGB7cn0KZmZpX2ZldmVyX21vbnRoX3RpbWVvZm1hbGFyaWEgPC0gZmZpX3RvdGFsICU+JQogIGRyb3BfbmEocGZfcmVjZW50OnB2X2hpc3RvcmljLCBhZ2VfY2F0LCBmZmlfaXNfZmV2ZXJfbW9udGgpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSByZWNlbnRfZXhwb3N1cmU6aGlzdG9yaWNhbF9leHBvc3VyZSwKICAgIG5hbWVzX3RvID0gImV4cG9zdXJlIiwKICAgIHZhbHVlc190byA9ICJyZXN1bHRfZXhwb3N1cmUiCiAgKSAlPiUKICBtdXRhdGUoCiAgICBleHBvc3VyZSA9IGNhc2Vfd2hlbigKICAgICAgZXhwb3N1cmUgPT0gInJlY2VudF9leHBvc3VyZSIgfiAiUmVjZW50IEV4cG9zdXJlIiwKICAgICAgZXhwb3N1cmUgPT0gImhpc3RvcmljYWxfZXhwb3N1cmUiIH4gIkhpc3RvcmljYWwgRXhwb3N1cmUiCiAgICApLAogICAgcmVzdWx0X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfZmV2ZXJfbW9udGgsIGFnZV9jYXQsIGV4cG9zdXJlKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X2V4cG9zdXJlID0gbWVhbihyZXN1bHRfZXhwb3N1cmUpKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2ZldmVyX21vbnRoIDwtIGZmaV9mZXZlcl9tb250aF90eXBlb2ZtYWxhcmlhICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgeSA9IGFnZV9jYXQsCiAgICAgIGdyb3VwID0gYWdlX2NhdAogICAgKQogICkgKwogIGdlb21fcGF0aCgKICAgIGNvbG9yID0gIiNiZGJkYmQiCiAgKSArCiAgZ2VvbV9wb2ludCgKICAgIGFlcyhjb2xvciA9IGV4cG9zdXJlKSwKICAgIHNpemUgPSAzCiAgKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19mZXZlcl9tb250aCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjIGxpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB5ID0gIkFnZSIsCiAgICB4ID0gIlNlcm9wb3NpdGl2aXR5IiwKICAgIHRpdGxlID0gc3RyX3dyYXAoIk1hbGFyaWEgc2Vyb3Bvc2l0aXZpdHkgYnkgdGltZSBvZiBwbGFzbW9kaXVtIGFuZCBwcmVzZW5jZSBvZiBmZXZlciBpbiB0aGUgbGFzdCBtb250aCIsIDEwMCkKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDE2X3Nlcm9fdGltZW9mbWFsYXJpYV9mZXZlcm1vbnRoLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2ZldmVyX21vbnRoLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyBSZWxhdGlvbiB3aXRoIEFudGltYWxhcmlhbCBEcnVncwoKIyMjIEJ5IDQgTWFsYXJpYQoKYGBge3J9CnNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICI0bWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfYW50aW1hbF9kcnVnX3VzZQopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfYW50aW1hbF9kcnVnX3VzZSksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDE5X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX2FudGltYWxfZHJ1Z191c2UKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX2FudGltYWxfZHJ1Z191c2UpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC42MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDIwX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc19hbnRpbWFsX2RydWdfdXNlCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9leHBvc3VyZSwKICAgICAgY29sb3IgPSBleHBvc3VyZSwKICAgICAgZ3JvdXAgPSBleHBvc3VyZQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc19hbnRpbWFsX2RydWdfdXNlKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBsaW1pdHMgPSBjKDAsIDAuNSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2FudGltYWxkcnVncwpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDIxX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9hbnRpbWFsZHJ1Z3MucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfYW50aW1hbGRydWdzLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIyBSZWxhdGlvbiB3aXRoIHRpbWUgb2Ygc29tZW9uZSBoYWQgbWFsYXJpYQoKIyMjIEJ5IGdlbmVyYWwgbWFsYXJpYQoKYGBge3J9CmZmaV80bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3RvdGFsICU+JSAKICBkcm9wX25hKG9ubHlfcHZfZXhwb3N1cmU6ZnJlZWRvbV9tYWxhcmlhLCAKICAgICAgICAgIGFnZV9jb2RlLCBmZmlfaXNfbWFsX2xpZmV0aW1lKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IG9ubHlfcHZfZXhwb3N1cmU6ZnJlZWRvbV9tYWxhcmlhLAogICAgbmFtZXNfdG8gPSAibWFsYXJpYSIsCiAgICB2YWx1ZXNfdG8gPSAicmVzdWx0X21hbGFyaWEiCiAgKSAlPiUgCiAgbXV0YXRlKAogICAgcmVzdWx0X21hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIHJlc3VsdF9tYWxhcmlhID09ICJQb3NpdGl2ZSIgfiAxLAogICAgICBUUlVFIH4gMAogICAgKSwKICAgIG1hbGFyaWEgPSBjYXNlX3doZW4oCiAgICAgIG1hbGFyaWEgPT0gIm9ubHlfcHZfZXhwb3N1cmUiIH4gIk9ubHkgUC4gdml2YXgiLAogICAgICBtYWxhcmlhID09ICJvbmx5X3BmX2V4cG9zdXJlIiB+ICJPbmx5IFAuIGZhbGNpcGFydW0iLAogICAgICBtYWxhcmlhID09ICJwdl9wZl9leHBvc3VyZSIgfiAiUC4gdml2YXggJiBmYWxjaXBhcnVtIEV4cG9zdXJlIiwKICAgICAgbWFsYXJpYSA9PSAiZnJlZWRvbV9tYWxhcmlhIiB+ICJGcmVlZG9tIGZyb20gTWFsYXJpYSIKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApICU+JQogIGdyb3VwX2J5KGZmaV9pc19tYWxfbGlmZXRpbWUsIGFnZV9jb2RlLCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkKCnNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lIDwtIGZmaV80bWFsYXJpYV9tYWxfbGlmZXRpbWUgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NvZGUsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgZmlsbCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX2FyZWEoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGltaXRzID0gYygxLCA4KSwKICAgIGJyZWFrcyA9IHNlcSgxLCA4LCAxKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJbMC0xMCkiLAogICAgICAiWzEwLTIwKSIsCiAgICAgICJbMjAtMzApIiwKICAgICAgIlszMC00MCkiLAogICAgICAiWzQwLTUwKSIsCiAgICAgICJbNTAtNjApIiwKICAgICAgIls2MC03MCkiLAogICAgICAiWzcwKykiCiAgICApLAogICAgZXhwYW5kID0gYygwLCAwKQogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX21hbF9saWZldGltZSkpICsKICBsYWJzKAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIsCiAgICB4ID0gIkFnZSIsCiAgICB0aXRsZSA9IHN0cl93cmFwKCJNYWxhcmlhIHNlcm9wb3NpdGl2aXR5IGJ5IHR5cGUgb2YgZXhwb3N1cmUsIHBsYXNtb2RpdW0gYW5kIGhvdyBtYW55IHRpbWVzIHRoZXkgdGhpbmsgdGhleSBoYXZlIGhhZCBtYWxhcmlhIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCgKICAgICAgYW5nbGUgPSA0NSwKICAgICAgdmp1c3QgPSAxLAogICAgICBoanVzdCA9IDEKICAgICksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgxLCAibGluZXMiKQogICkKCnNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MjJfc2Vyb180b2ZtYWxhcmlhX21hbF9saWZldGltZS5wbmciLAogIHNlcm9fNG1hbGFyaWFfbWFsX2xpZmV0aW1lLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA1CikKYGBgCgojIyMgQnkgUmVjZW50IE1hbGFyaWEKCmBgYHtyfQpmZmlfcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3RvdGFsICU+JSAKICBkcm9wX25hKG9ubHlfcHZfcmVjZW50OmZyZWVkb21fbWFsYXJpYV9yZWNlbnQsIAogICAgICAgICAgYWdlX2NvZGUsIGZmaV9pc19tYWxfbGlmZXRpbWUpICU+JSAKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gb25seV9wdl9yZWNlbnQ6ZnJlZWRvbV9tYWxhcmlhX3JlY2VudCwKICAgIG5hbWVzX3RvID0gIm1hbGFyaWEiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9tYWxhcmlhIgogICkgJT4lIAogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJvbmx5X3B2X3JlY2VudCIgfiAiT25seSBQLiB2aXZheCBSZWNlbnQiLAogICAgICBtYWxhcmlhID09ICJvbmx5X3BmX3JlY2VudCIgfiAiT25seSBQLiBmYWxjaXBhcnVtIFJlY2VudCIsCiAgICAgIG1hbGFyaWEgPT0gInB2X3BmX3JlY2VudCIgfiAiUC4gdml2YXggJiBmYWxjaXBhcnVtIFJlY2VudCIsCiAgICAgIG1hbGFyaWEgPT0gImZyZWVkb21fbWFsYXJpYV9yZWNlbnQiIH4gIkZyZWVkb20gZnJvbSBNYWxhcmlhIFJlY2VudCIKICAgICksCiAgICBhY3Jvc3MoCiAgICAgIGMoZmZpX2lzX2NvbW11bml0eTpmZmlfaXNfaGVhbHRoX2ZhY2lsaXR5X25hbWUpLAogICAgICBzdHJfdG9fdGl0bGUKICAgICkKICApICU+JQogIGdyb3VwX2J5KGZmaV9pc19tYWxfbGlmZXRpbWUsIGFnZV9jb2RlLCBtYWxhcmlhKSAlPiUKICBzdW1tYXJpc2UocmVzdWx0X21hbGFyaWEgPSBtZWFuKHJlc3VsdF9tYWxhcmlhKSkKCnNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX3JlY2VudG1hbGFyaWFfbWFsX2xpZmV0aW1lICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jb2RlLAogICAgICB5ID0gcmVzdWx0X21hbGFyaWEsCiAgICAgIGZpbGwgPSBtYWxhcmlhCiAgICApCiAgKSArCiAgZ2VvbV9hcmVhKCkgKwogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoMSwgOCksCiAgICBicmVha3MgPSBzZXEoMSwgOCwgMSksCiAgICBsYWJlbHMgPSBjKAogICAgICAiWzAtMTApIiwKICAgICAgIlsxMC0yMCkiLAogICAgICAiWzIwLTMwKSIsCiAgICAgICJbMzAtNDApIiwKICAgICAgIls0MC01MCkiLAogICAgICAiWzUwLTYwKSIsCiAgICAgICJbNjAtNzApIiwKICAgICAgIls3MCspIgogICAgKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICBleHBhbmQgPSBjKDAsIDApCiAgKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZmaV9pc19tYWxfbGlmZXRpbWUpKSArCiAgbGFicygKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiLAogICAgeCA9ICJBZ2UiLAogICAgdGl0bGUgPSBzdHJfd3JhcCgiTWFsYXJpYSBzZXJvcG9zaXRpdml0eSBieSByZWNlbnQgZXhwb3N1cmUgYW5kIGhvdyBtYW55IHRpbWVzIHRoZXkgdGhpbmsgdGhleSBoYXZlIGhhZCBtYWxhcmlhIiwgMTAwKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCgKICAgICAgYW5nbGUgPSA0NSwKICAgICAgdmp1c3QgPSAxLAogICAgICBoanVzdCA9IDEKICAgICksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgxLCAibGluZXMiKQogICkKCnNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyM19zZXJvX3JlY2VudF9tYWxhcmlhX21hbF9saWZldGltZS5wbmciLAogIHNlcm9fcmVjZW50bWFsYXJpYV9tYWxfbGlmZXRpbWUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDExLAogIGhlaWdodCA9IDUKKQpgYGAKCgojIyMgQnkgSGlzdG9yaWMgTWFsYXJpYQoKYGBge3J9CmZmaV9oaXN0b3JpY21hbGFyaWFfbWFsX2xpZmV0aW1lIDwtIGZmaV90b3RhbCAlPiUgCiAgZHJvcF9uYShvbmx5X3B2X2hpc3RvcmljOmZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYywgCiAgICAgICAgICBhZ2VfY29kZSwgZmZpX2lzX21hbF9saWZldGltZSkgJT4lIAogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBvbmx5X3B2X2hpc3RvcmljOmZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYywKICAgIG5hbWVzX3RvID0gIm1hbGFyaWEiLAogICAgdmFsdWVzX3RvID0gInJlc3VsdF9tYWxhcmlhIgogICkgJT4lIAogIG11dGF0ZSgKICAgIHJlc3VsdF9tYWxhcmlhID0gY2FzZV93aGVuKAogICAgICByZXN1bHRfbWFsYXJpYSA9PSAiUG9zaXRpdmUiIH4gMSwKICAgICAgVFJVRSB+IDAKICAgICksCiAgICBtYWxhcmlhID0gY2FzZV93aGVuKAogICAgICBtYWxhcmlhID09ICJvbmx5X3B2X2hpc3RvcmljIiB+ICJPbmx5IFAuIHZpdmF4IEhpc3RvcmljIiwKICAgICAgbWFsYXJpYSA9PSAib25seV9wZl9oaXN0b3JpYyIgfiAiT25seSBQLiBmYWxjaXBhcnVtIEhpc3RvcmljIiwKICAgICAgbWFsYXJpYSA9PSAicHZfcGZfaGlzdG9yaWMiIH4gIlAuIHZpdmF4ICYgZmFsY2lwYXJ1bSBIaXN0b3JpYyIsCiAgICAgIG1hbGFyaWEgPT0gImZyZWVkb21fbWFsYXJpYV9oaXN0b3JpYyIgfiAiRnJlZWRvbSBmcm9tIE1hbGFyaWEgSGlzdG9yaWMiCiAgICApLAogICAgYWNyb3NzKAogICAgICBjKGZmaV9pc19jb21tdW5pdHk6ZmZpX2lzX2hlYWx0aF9mYWNpbGl0eV9uYW1lKSwKICAgICAgc3RyX3RvX3RpdGxlCiAgICApCiAgKSAlPiUKICBncm91cF9ieShmZmlfaXNfbWFsX2xpZmV0aW1lLCBhZ2VfY29kZSwgbWFsYXJpYSkgJT4lCiAgc3VtbWFyaXNlKHJlc3VsdF9tYWxhcmlhID0gbWVhbihyZXN1bHRfbWFsYXJpYSkpCgpzZXJvX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUgPC0gZmZpX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NvZGUsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgZmlsbCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX2FyZWEoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGltaXRzID0gYygxLCA4KSwKICAgIGJyZWFrcyA9IHNlcSgxLCA4LCAxKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJbMC0xMCkiLAogICAgICAiWzEwLTIwKSIsCiAgICAgICJbMjAtMzApIiwKICAgICAgIlszMC00MCkiLAogICAgICAiWzQwLTUwKSIsCiAgICAgICJbNTAtNjApIiwKICAgICAgIls2MC03MCkiLAogICAgICAiWzcwKykiCiAgICApLAogICAgZXhwYW5kID0gYygwLCAwKQogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGV4cGFuZCA9IGMoMCwgMCkKICApICsKICBmYWNldF93cmFwKHZhcnMoZmZpX2lzX21hbF9saWZldGltZSkpICsKICBsYWJzKAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIsCiAgICB4ID0gIkFnZSIsCiAgICB0aXRsZSA9IHN0cl93cmFwKCJNYWxhcmlhIHNlcm9wb3NpdGl2aXR5IGJ5IGhpc3RvcmljIGV4cG9zdXJlIGFuZCBob3cgbWFueSB0aW1lcyB0aGV5IHRoaW5rIHRoZXkgaGF2ZSBoYWQgbWFsYXJpYSIsIDEwMCkKICApICsKICBndWlkZXMoCiAgICBmaWxsID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9maWxsX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoCiAgICAgIGFuZ2xlID0gNDUsCiAgICAgIHZqdXN0ID0gMSwKICAgICAgaGp1c3QgPSAxCiAgICApLAogICAgcGFuZWwuc3BhY2luZyA9IHVuaXQoMSwgImxpbmVzIikKICApCgpzZXJvX2hpc3RvcmljbWFsYXJpYV9tYWxfbGlmZXRpbWUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyNF9zZXJvX2hpc3RvcmljX21hbGFyaWFfbWFsX2xpZmV0aW1lLnBuZyIsCiAgc2Vyb19oaXN0b3JpY21hbGFyaWFfbWFsX2xpZmV0aW1lLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA1CikKYGBgCgoKIyMgUmVsYXRpb24gd2hlcmUgc29tZW9uZSB1c3VhbGx5IGJhdGhlCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGU8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZQpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDI1X3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjYwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MjZfc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZS5wbmciLAogIHNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFRpbWUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInRpbWVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3BsYWNlX3Nob3dlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfcGxhY2Vfc2hvd2VyKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUpCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF91c3N1YWx5YmF0aGUKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QyN19zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfdXNzdWFseWJhdGhlLnBuZyIsCiAgc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3Vzc3VhbHliYXRoZSwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gOC41CikKYGBgCgoKIyMgUmVsYXRpb24gd2l0aCB0aG9zZSB3aG8gaGF2ZSBhIG1vc3F1aXRvIG5ldAoKIyMjIEJ5IDQgTWFsYXJpYQoKYGBge3J9CnNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAiNG1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX21vc3FfbmV0CikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc19tb3NxX25ldCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41MCkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0CmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90Mjhfc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAidHlwZW9mbWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfbW9zcV9uZXQKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX21vc3FfbmV0KSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjYwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDI5X3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X21vc3F1aXRuZXQsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFRpbWUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0IDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc19tb3NxX25ldAopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfbW9zcV9uZXQpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICNsaW1pdHMgPSBjKDAsIDAuNSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X21vc3F1aXRuZXQKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzMF9zZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfbW9zcXVpdG5ldC5wbmciLAogIHNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9tb3NxdWl0bmV0LAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIFJlbGF0aW9uIHdpdGggdGhvc2Ugd2hvIGhhdmUgYSB0cmlwIGluIHRoZSBsYXN0IG1vbnRoCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGggPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGZmaV9pc190cmlwX21vbnRoCikgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gYWdlX2NhdCwKICAgICAgeSA9IHJlc3VsdF9tYWxhcmlhLAogICAgICBjb2xvciA9IG1hbGFyaWEsCiAgICAgIGdyb3VwID0gbWFsYXJpYQogICAgKQogICkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoCiAgICB2YXJzKGZmaV9pc190cmlwX21vbnRoKSwKICAgIHZhcnMoZmZpX2lzX2Rpc3RyaWN0KSAgICAKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAjbGltaXRzID0gYygwLCAwLjUwKQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aApgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDMxX3Nlcm9fNG1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoLnBuZyIsCiAgc2Vyb180bWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyMjIEJ5IFR5cGUgb2YgTWFsYXJpYQoKYGBge3J9CnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGggPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgInR5cGVvZm1hbGFyaWEiLAogIGFnZV9jYXQsCiAgZmZpX2lzX3RyaXBfbW9udGgKKSAlPiUKICBnZ3Bsb3QoCiAgICBhZXMoCiAgICAgIHggPSBhZ2VfY2F0LAogICAgICB5ID0gcmVzdWx0X2V4cG9zdXJlLAogICAgICBjb2xvciA9IGV4cG9zdXJlLAogICAgICBncm91cCA9IGV4cG9zdXJlCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfZ3JpZCgKICAgIHZhcnMoZmZpX2lzX3RyaXBfbW9udGgpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgICNsaW1pdHMgPSBjKDAsIDAuNjApCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkKCnNlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzMl9zZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoLnBuZyIsCiAgc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aCwKICBkcGkgPSAzMDAsCiAgYmcgPSAid2hpdGUiLAogIHdpZHRoID0gMTIsCiAgaGVpZ2h0ID0gOC41CikKYGBgCgojIyMgQnkgVGltZSBvZiBNYWxhcmlhCgpgYGB7cn0Kc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aCA8LSBzZXJvcG9zaXRpdnlfc3VtbWFyaXNlKAogIGZmaV90b3RhbCwKICAidGltZW9mbWFsYXJpYSIsCiAgYWdlX2NhdCwKICBmZmlfaXNfdHJpcF9tb250aAopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhmZmlfaXNfdHJpcF9tb250aCksCiAgICB2YXJzKGZmaV9pc19kaXN0cmljdCkgICAgCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgI2xpbWl0cyA9IGMoMCwgMC41KQogICkgKwogIGxhYnMoCiAgICB4ID0gIkFnZSIsCiAgICB5ID0gIlNlcm9wb3NpdGl2aXR5IgogICkgKwogIGd1aWRlcygKICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKCJNYWxhcmlhIikKICApICsKICBpbm5vdmFyOjpzY2FsZV9jb2xvcl9pbm5vdmEoIm5wciIpICsKICB0aGVtZV9idygpCgpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfdHJpcG1vbnRoCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKAogICIuLzAyX291dHB1dC9wbG90cy9wbG90MzNfc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X3RyaXBtb250aC5wbmciLAogIHNlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF90cmlwbW9udGgsCiAgZHBpID0gMzAwLAogIGJnID0gIndoaXRlIiwKICB3aWR0aCA9IDEyLAogIGhlaWdodCA9IDguNQopCmBgYAoKIyBEZXNjcmlwdGl2ZSAwMV9kYXRhCgpgYGB7ciBldmFsPUZBTFNFfQpwbG90XzRfMiA8LSBmZmlfdG90YWwgJT4lCiAgZmlsdGVyKGZmaV9pc19tYWxhcmlhICVpbiUgYygiTm8iLCAiWWVzIikpICU+JQogIGRyb3BfbmEoYWdlX2NhdCwgcHZfaGlzdG9yaWMpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfZ2VuZGVyID0gcGFzdGUoZ2VuZGVyLCBmZmlfaXNfbWFsYXJpYSkKICApICU+JQogIGNvdW50KHB2X2hpc3RvcmljLCBhZ2VfY2F0LCBtYWxhcmlhX2dlbmRlcikgJT4lCiAgbXV0YXRlKFBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pKSAlPiUKICBtdXRhdGUoCiAgICBQZXJjZW50YWdlID0gY2FzZV93aGVuKAogICAgICBzdHJfZGV0ZWN0KG1hbGFyaWFfZ2VuZGVyLCAiRmVtYWxlIikgfiBQZXJjZW50YWdlICogLTEsCiAgICAgIFRSVUUgfiBQZXJjZW50YWdlCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeSA9IGFnZV9jYXQsCiAgICB4ID0gUGVyY2VudGFnZSwKICAgIGZpbGwgPSBtYWxhcmlhX2dlbmRlcgogICkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2socmV2ZXJzZSA9IFRSVUUpLAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIEdyb3VwIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiUG9wdWxhdGlvbiBzdHJ1Y3R1cmUgYnkgYWdlIGdyb3VwcywgZ2VuZGVyIGFuZCBtYWxhcmlhIHRyYW5zbWlzc2lvbiIKICApICsKICBmYWNldF93cmFwKHZhcnMocHZfaGlzdG9yaWMpKSArIAogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoLTAuMjUsIDAuMjUpLAogICAgYnJlYWtzID0gc2VxKC0wLjI1LCAwLjI1LCAwLjA1KSwKICAgIGxhYmVscyA9IGMocGFzdGUwKHNlcSgyNSwgMCwgLTUpLCAiJSIpLCBwYXN0ZTAoc2VxKDUsIDI1LCA1KSwgIiUiKSkKICApICsKICAjIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgKICAgIHR5cGUgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJucHIiKSg0KSwKICAgIGxpbWl0cyA9IGMoIk1hbGUgWWVzIiwgIk1hbGUgTm8iLCAiRmVtYWxlIE5vIiwgIkZlbWFsZSBZZXMiKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIkhhdmUgeW91IGV2ZXIgXG5oYWQgbWFsYXJpYT8iKQogICkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgaGp1c3QgPSAwLjUsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KAogICAgICBzaXplID0gMTIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxMiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDUsIDE1LCA1LCAxNSkKICApCmBgYAoKIyBEZXNjcmlwdGl2ZSAwMV9kYXRhCgpgYGB7ciBldmFsPUZBTFNFfQpwbG90XzRfMiA8LSBmZmlfdG90YWwgJT4lCiAgZmlsdGVyKGZmaV9pc19tYWxhcmlhICVpbiUgYygiTm8iLCAiWWVzIikpICU+JQogIGRyb3BfbmEoYWdlX2NhdCwgcHZfaGlzdG9yaWMpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfZ2VuZGVyID0gcGFzdGUoZ2VuZGVyLCBmZmlfaXNfbWFsYXJpYSkKICApICU+JQogIGNvdW50KHB2X2hpc3RvcmljLCBhZ2VfY2F0LCBtYWxhcmlhX2dlbmRlcikgJT4lCiAgbXV0YXRlKFBlcmNlbnRhZ2UgPSBuIC8gc3VtKG4pKSAlPiUKICBtdXRhdGUoCiAgICBQZXJjZW50YWdlID0gY2FzZV93aGVuKAogICAgICBzdHJfZGV0ZWN0KG1hbGFyaWFfZ2VuZGVyLCAiRmVtYWxlIikgfiBQZXJjZW50YWdlICogLTEsCiAgICAgIFRSVUUgfiBQZXJjZW50YWdlCiAgICApCiAgKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeSA9IGFnZV9jYXQsCiAgICB4ID0gUGVyY2VudGFnZSwKICAgIGZpbGwgPSBtYWxhcmlhX2dlbmRlcgogICkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2socmV2ZXJzZSA9IFRSVUUpLAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgbGFicygKICAgIHggPSAiQWdlIEdyb3VwIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiUG9wdWxhdGlvbiBzdHJ1Y3R1cmUgYnkgYWdlIGdyb3VwcywgZ2VuZGVyIGFuZCBtYWxhcmlhIHRyYW5zbWlzc2lvbiIKICApICsKICBmYWNldF93cmFwKHZhcnMocHZfaGlzdG9yaWMpKSArIAogIHNjYWxlX3hfY29udGludW91cygKICAgIGxpbWl0cyA9IGMoLTAuMjUsIDAuMjUpLAogICAgYnJlYWtzID0gc2VxKC0wLjI1LCAwLjI1LCAwLjA1KSwKICAgIGxhYmVscyA9IGMocGFzdGUwKHNlcSgyNSwgMCwgLTUpLCAiJSIpLCBwYXN0ZTAoc2VxKDUsIDI1LCA1KSwgIiUiKSkKICApICsKICAjIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgKICAgIHR5cGUgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJucHIiKSg0KSwKICAgIGxpbWl0cyA9IGMoIk1hbGUgWWVzIiwgIk1hbGUgTm8iLCAiRmVtYWxlIE5vIiwgIkZlbWFsZSBZZXMiKQogICkgKwogIGd1aWRlcygKICAgIGZpbGwgPSBndWlkZV9sZWdlbmQoIkhhdmUgeW91IGV2ZXIgXG5oYWQgbWFsYXJpYT8iKQogICkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgaGp1c3QgPSAwLjUsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KAogICAgICBzaXplID0gMTIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxMiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDUsIDE1LCA1LCAxNSkKICApCmBgYAoKIyMgU2Fua2V5X3Nlcm9wb3NpdGl2ZQoKCmBgYHtyfQpsaWJyYXJ5KGdnc2Fua2V5KQoKZmZpX2Zvcm1hdF9zYW5rZXkgPC0gZmZpX3RvdGFsICU+JQogIG11dGF0ZSgKICAgIGZmaV9pc19hY2Nlc3NfbWFsYXJpYV95bl9oZiA9IGZhY3RvcigKICAgICAgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmLAogICAgICBsYWJlbCA9IGMoIk5vIiwgIlllcyIpCiAgICApLAogICAgZmZpX2lzX21hbF9saWZldGltZSA9IGFzLmNoYXJhY3RlcihmZmlfaXNfbWFsX2xpZmV0aW1lKSwKICAgIGZmaV9pc19tYWxfbGlmZXRpbWUgPSByZXBsYWNlX25hKGZmaV9pc19tYWxfbGlmZXRpbWUsICIwIHRpbWVzIiksCiAgICBmZmlfaXNfbWFsX2xpZmV0aW1lID0gZmFjdG9yKAogICAgICBmZmlfaXNfbWFsX2xpZmV0aW1lLAogICAgICBsYWJlbHMgPSBjKAogICAgICAgICIwIHRpbWVzIiwKICAgICAgICAiMSB0byAzIHRpbWVzIiwKICAgICAgICAiMyB0byA3IHRpbWVzIiwKICAgICAgICAiTW9yZSB0aGFuIDcgdGltZXMiCiAgICAgICkKICAgICkKICApCgpzYW5rZXlfc2Vyb3Bvc2l0aXZlX2Fuc3cxIDwtIGZmaV9mb3JtYXRfc2Fua2V5ICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSBjKHJlY2VudF9leHBvc3VyZSwgZmZpX2lzX21hbF9saWZldGltZSwgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmKSwKICAgIG5hbWVzX3RvID0gIm1hbGFyaWFfYmVoYXZpb3IxIiwKICAgIHZhbHVlc190byA9ICJtYWxhcmlhX2Fuc3cxIgogICkgJT4lCiAgY291bnQobWFsYXJpYV9iZWhhdmlvcjEsIG1hbGFyaWFfYW5zdzEpICU+JQogIGdyb3VwX2J5KG1hbGFyaWFfYmVoYXZpb3IxKSAlPiUKICBtdXRhdGUoCiAgICBwZXJjZW50YWdlID0gc2NhbGVzOjpwZXJjZW50KAogICAgICBuIC8gc3VtKG4pLAogICAgICBhY2N1cmFjeSA9IDAuMQogICAgKQogICkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSgKICAgIG1hbGFyaWFfYmVoYXZpb3IxID0gZmN0X3JlbGV2ZWwoCiAgICAgIG1hbGFyaWFfYmVoYXZpb3IxLAogICAgICAiZmZpX2lzX21hbF9saWZldGltZSIsCiAgICAgICJmZmlfaXNfYWNjZXNzX21hbGFyaWFfeW5faGYiLAogICAgICAicmVjZW50X2V4cG9zdXJlIgogICAgKSwKICAgIG1hbGFyaWFfcGVyY2VudDEgPSBwYXN0ZTAoCiAgICAgIG1hbGFyaWFfYW5zdzEsCiAgICAgIHBhc3RlMCgiXG4oIiwgcGVyY2VudGFnZSwgIikiKQogICAgKSwKICAgIG1hbGFyaWFfcGVyY2VudDEgPSBhc19mYWN0b3IobWFsYXJpYV9wZXJjZW50MSkKICApICU+JQogIHNlbGVjdChtYWxhcmlhX2JlaGF2aW9yMSwgbWFsYXJpYV9hbnN3MSwgbWFsYXJpYV9wZXJjZW50MSkKCgpzYW5rZXlfc2Vyb3Bvc2l0aXZlIDwtIGZmaV9mb3JtYXRfc2Fua2V5ICU+JQogIGRyb3BfbmEoZmZpX2lzX21hbF9saWZldGltZSwgCiAgZmZpX2lzX2FjY2Vzc19tYWxhcmlhX3luX2hmLAogIHJlY2VudF9leHBvc3VyZQogICkgJT4lCiAgbWFrZV9sb25nKAogICAgZmZpX2lzX21hbF9saWZldGltZSwKICAgIGZmaV9pc19hY2Nlc3NfbWFsYXJpYV95bl9oZiwgCiAgICByZWNlbnRfZXhwb3N1cmUKICApICU+JQogIGxlZnRfam9pbigKICAgIHNhbmtleV9zZXJvcG9zaXRpdmVfYW5zdzEsCiAgICAgIGJ5ID0gYygKICAgICAgICAieCIgPSAibWFsYXJpYV9iZWhhdmlvcjEiLAogICAgICAgICJub2RlIiA9ICJtYWxhcmlhX2Fuc3cxIgogICAgICApCiAgKSAlPiUKICBtdXRhdGUoCiAgICBub2RlID0gbWFsYXJpYV9wZXJjZW50MSwKICAgIG5vZGUgPSBmY3RfcmV2KG5vZGUpCiAgKSAlPiUKICBzZWxlY3QoLW1hbGFyaWFfcGVyY2VudDEpICU+JQogIGxlZnRfam9pbigKICAgIHNhbmtleV9zZXJvcG9zaXRpdmVfYW5zdzEsCiAgICBieSA9IGMoCiAgICAgICJuZXh0X3giID0gIm1hbGFyaWFfYmVoYXZpb3IxIiwKICAgICAgIm5leHRfbm9kZSIgPSAibWFsYXJpYV9hbnN3MSIKICAgICkKICApICU+JQogIG11dGF0ZShuZXh0X25vZGUgPSBtYWxhcmlhX3BlcmNlbnQxKSAlPiUKICBzZWxlY3QoLW1hbGFyaWFfcGVyY2VudDEpICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0geCwKICAgIG5leHRfeCA9IG5leHRfeCwKICAgIG5vZGUgPSBub2RlLAogICAgbmV4dF9ub2RlID0gbmV4dF9ub2RlLAogICAgZmlsbCA9IGZhY3Rvcihub2RlKSwKICAgIGxhYmVsID0gbm9kZQogICkpICsKICBnZW9tX3NhbmtleSgKICAgIGZsb3cuYWxwaGEgPSAuOCwKICAgIG5vZGUuY29sb3IgPSAiZ3JheTMwIgogICkgKwogIGdlb21fc2Fua2V5X2xhYmVsKHNpemUgPSA0LCBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSAiZ3JheTMwIikgKwogIHNjYWxlX3hfZGlzY3JldGUoCiAgICBsYWJlbHMgPSBzdHJfd3JhcCgKICAgICAgYygKICAgICAgICAiSG93IG1hbnkgdGltZXMgZG8geW91IHRoaW5rIHlvdSBoYXZlIGhhZCBtYWxhcmlhIGluIHlvdXIgbGlmZT8iLAogICAgICAgICJJZiB5b3UgaGFkIG1hbGFyaWEsIHdvdWxkIHlvdSBnbyB0byB0aGUgaGVhbHRoIGZhY2lsaXR5PyIsCiAgICAgICAgIlJlY2VudCBleHBvc3VyZSB0byBhbnkgdHlwZSBvZiBwbGFzbW9kaXVtIgogICAgICApLAogICAgICAzMAogICAgKQogICkgKwogIHRoZW1lX3NhbmtleShiYXNlX3NpemUgPSAxOCkgKwogIGlubm92YXI6OnNjYWxlX2ZpbGxfaW5ub3ZhKCJucHIiKSArCiAgbGFicygKICAgIHggPSBOVUxMLAogICAgdGl0bGUgPSAiQmVoYXZpb3VyIGFzc29jaWF0ZWQgd2l0aCByZWNlbnQgbWFsYXJpYSBleHBvc3VyZSIKICApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbig1LCA1LCA1LCA1KQogICkKCmBgYAoKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKCIuLzAyX291dHB1dC9wbG90cy9wbG90MzRfc2Fua2V5X3Nlcm9wb3NpdGl2ZS5wbmciLAogICAgICAgc2Fua2V5X3Nlcm9wb3NpdGl2ZSwKICAgICAgIGhlaWdodCA9IDcsCiAgICAgICB3aWR0aCA9IDE0LAogICAgICAgZHBpID0gMzAwKQpgYGAKCiMjIFJlbGF0aW9uIGdlbmRlciBhbmQgb2N1cGF0aW9uCgojIyMgQnkgNCBNYWxhcmlhCgpgYGB7cn0Kc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXJfZWNvbm9taWMgPC0gc2Vyb3Bvc2l0aXZ5X3N1bW1hcmlzZSgKICBmZmlfdG90YWwsCiAgIjRtYWxhcmlhIiwKICBlY29ub21pY19hY3Rpdml0aWVzLAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGVjb25vbWljX2FjdGl2aXRpZXMsCiAgICAgIHkgPSByZXN1bHRfbWFsYXJpYSwKICAgICAgY29sb3IgPSBtYWxhcmlhLAogICAgICBncm91cCA9IG1hbGFyaWEKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40MCkKICApICsKICBsYWJzKAogICAgeCA9ICJFY29ub21pYyBBY3Rpdml0aWVzIiwKICAgIHkgPSAiU2Vyb3Bvc2l0aXZpdHkiCiAgKSArCiAgZ3VpZGVzKAogICAgY29sb3IgPSBndWlkZV9sZWdlbmQoIk1hbGFyaWEiKQogICkgKwogIGlubm92YXI6OnNjYWxlX2NvbG9yX2lubm92YSgibnByIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoCiAgICAgIGFuZ2xlID0gNDUsCiAgICAgIHZqdXN0ID0gMSwKICAgICAgaGp1c3QgPSAxCiAgICApCiAgKQoKc2Vyb180bWFsYXJpYV9kaXN0cmljdF9nZW5kZXJfZWNvbm9taWMKYGBgCgpgYGB7ciBldmFsPUZBTFNFfQpnZ3NhdmUoCiAgIi4vMDJfb3V0cHV0L3Bsb3RzL3Bsb3QzNV9zZXJvXzRtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcl9lY29ub21pYy5wbmciLAogIHNlcm9fNG1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyX2Vjb25vbWljLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMSwKICBoZWlnaHQgPSA3LjUsCiAgc2NhbGUgPSAwLjkKKQpgYGAKCiMjIyBCeSBUeXBlIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0eXBlb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190eXBlb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDExX3Nlcm9fdHlwZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3R5cGVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCiMjIyBCeSBUaW1lIG9mIE1hbGFyaWEKCmBgYHtyfQpzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyIDwtIHNlcm9wb3NpdGl2eV9zdW1tYXJpc2UoCiAgZmZpX3RvdGFsLAogICJ0aW1lb2ZtYWxhcmlhIiwKICBhZ2VfY2F0LAogIGdlbmRlcgopICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGFnZV9jYXQsCiAgICAgIHkgPSByZXN1bHRfZXhwb3N1cmUsCiAgICAgIGNvbG9yID0gZXhwb3N1cmUsCiAgICAgIGdyb3VwID0gZXhwb3N1cmUKICAgICkKICApICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKAogICAgdmFycyhnZW5kZXIpLAogICAgdmFycyhmZmlfaXNfZGlzdHJpY3QpICAgIAogICkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAgIGxpbWl0cyA9IGMoMCwgMC40NSkKICApICsKICBsYWJzKAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJTZXJvcG9zaXRpdml0eSIKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZCgiTWFsYXJpYSIpCiAgKSArCiAgaW5ub3Zhcjo6c2NhbGVfY29sb3JfaW5ub3ZhKCJucHIiKSArCiAgdGhlbWVfYncoKQoKc2Vyb190aW1lb2ZtYWxhcmlhX2Rpc3RyaWN0X2dlbmRlcgpgYGAKCmBgYHtyIGV2YWw9RkFMU0V9Cmdnc2F2ZSgKICAiLi8wMl9vdXRwdXQvcGxvdHMvcGxvdDEyX3Nlcm9fdGltZW9mbWFsYXJpYV9kaXN0cmljdF9nZW5kZXIucG5nIiwKICBzZXJvX3RpbWVvZm1hbGFyaWFfZGlzdHJpY3RfZ2VuZGVyLAogIGRwaSA9IDMwMCwKICBiZyA9ICJ3aGl0ZSIsCiAgd2lkdGggPSAxMiwKICBoZWlnaHQgPSA4LjUKKQpgYGAKCgojIE1hcHMKCmBgYHtyfQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGxlYWZsZXQpCmBgYAoKYGBge3J9CmZmaV90b3RhbF9ncHMgPC0gZmZpX3RvdGFsICU+JQogIHNlbGVjdCgKICAgIGZmaV9pc19jb2RfY29tOmZmaV9pc19jb2RfaW5kLAogICAgcGZfcmVjZW50OnB2X2hpc3RvcmljLAogICAgcHZfZXhwb3N1cmU6aGlzdG9yaWNhbF9leHBvc3VyZQogICkgJT4lCiAgbGVmdF9qb2luKAogICAgZmZpX2hvdXNlaG9sZCAlPiUKICAgICAgc2VsZWN0KAogICAgICAgIGZmaV9oX2NvZGVfY29tbXVuaXR5OmZmaV9oX2NvZGVfaG91c2Vob2xkLAogICAgICAgIGZmaV9oX2NvbW11bml0eQogICAgICApLAogICAgYnkgPSBjKAogICAgICAiZmZpX2lzX2NvZF9jb20iID0gImZmaV9oX2NvZGVfY29tbXVuaXR5IiwKICAgICAgImZmaV9pc19jb2RfaG91c2Vob2xkIiA9ICJmZmlfaF9jb2RlX2hvdXNlaG9sZCIKICAgICkKICApIAoKZmZpX2hvdXNlaG9sZF9ncHMgPC0gZmZpX3RvdGFsX2dwcyAlPiUKICBzZWxlY3QoCiAgICBmZmlfaXNfY29kX2NvbTpmZmlfaXNfY29kX2hvdXNlaG9sZCwKICAgIGZmaV9oX2NvbW11bml0eSwKICAgIHJlY2VudF9leHBvc3VyZQogICkgJT4lCiAgbXV0YXRlKAogICAgcmVjZW50X2V4cG9zdXJlID0gY2FzZV93aGVuKAogICAgICByZWNlbnRfZXhwb3N1cmUgPT0gIlBvc2l0aXZlIiB+IDEsCiAgICAgIFRSVUUgfiAwCiAgICApCiAgKSAlPiUKICBncm91cF9ieSgKICAgIGFjcm9zcyhjKGZmaV9pc19jb2RfY29tOmZmaV9oX2NvbW11bml0eSkpCiAgKSAlPiUKICBzdW1tYXJpc2UoCiAgICByZWNlbnRfZXhwb3N1cmUgPSBtZWFuKHJlY2VudF9leHBvc3VyZSkKICApICU+JQogIHVuZ3JvdXAoKQogICMgbXV0YXRlKAogICMgICBjb2xvcl9tYXJrZXIgPSBjYXNlX3doZW4oCiAgIyAgICAgcmVjZW50X2V4cG9zdXJlID09IDAgfiAicmVkIiwKICAjICAgICBUUlVFIH4gImJsYWNrIgogICMgICApCiAgIyApCgpmZmlfaG91c2Vob2xkX2dwcyA8LSBmZmlfaG91c2Vob2xkX2dwcyAlPiUKICBsZWZ0X2pvaW4oCiAgICBmZmlfaG91c2Vob2xkICU+JQogICAgICBzZWxlY3QoCiAgICAgICAgZmZpX2hfY29kZV9jb21tdW5pdHk6ZmZpX2hfY29kZV9ob3VzZWhvbGQsCiAgICAgICAgZmZpX2hfZGlzdHJpY3QsCiAgICAgICAgZmZpX2dwc19sb25nLAogICAgICAgIGZmaV9ncHNfbGF0CiAgICAgICksCiAgICBieSA9IGMoCiAgICAgICJmZmlfaXNfY29kX2NvbSIgPSAiZmZpX2hfY29kZV9jb21tdW5pdHkiLAogICAgICAiZmZpX2lzX2NvZF9ob3VzZWhvbGQiID0gImZmaV9oX2NvZGVfaG91c2Vob2xkIgogICAgKQogICkgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfaG91c2Vob2xkX2lkID0gcGFzdGUwKGZmaV9pc19jb2RfY29tLCBmZmlfaXNfY29kX2hvdXNlaG9sZCksCiAgICBmZmlfaXNfY29kX2NvbV9sYWJlbCA9IHBhc3RlMCgKICAgICAgIkNvZDogIiwKICAgICAgZmZpX2lzX2NvZF9ob3VzZWhvbGQsCiAgICAgICIgLSAiLAogICAgICBzdHJfdG9fdGl0bGUoZmZpX2hfY29tbXVuaXR5KSwKICAgICAgIiAoIiwKICAgICAgc3RyX3RvX3RpdGxlKGZmaV9oX2Rpc3RyaWN0KSwKICAgICAgIikiCiAgICApCiAgKSAlPiUKICBzdF9hc19zZigKICAgIGNvb3JkcyA9IGMoImZmaV9ncHNfbG9uZyIsICJmZmlfZ3BzX2xhdCIpLAogICAgY3JzID0gNDMyNgogICkgCiAgCgogIAojIGNvbG9yc19wYWwgPC0gcmV2KGlubm92YXI6Ojppbm5vdmFfcGFsZXR0ZXNbWyJlY29tc3QiXV0pCiMgcGFsIDwtIGNvbG9yTnVtZXJpYygKIyAgIGNvbG9yUmFtcChjb2xvcnNfcGFsKSwKIyAgIGZmaV9ob3VzZWhvbGRfZ3BzJHJlY2VudF9leHBvc3VyZQojICkKCnBhbCA8LSBjb2xvck51bWVyaWMoCiAgaGNsLmNvbG9ycygxNywgcGFsZXR0ZSA9ICJ6aXNzb3UiKSwKICBmZmlfaG91c2Vob2xkX2dwcyRyZWNlbnRfZXhwb3N1cmUKKQoKIyBpY29uc19ob3VzZWhvbGQgPC0gYXdlc29tZUljb25zKAojICAgaWNvbiA9ICJpb3MtaG9tZSIsCiMgICBpY29uQ29sb3IgPSAiYmxhY2siLAojICAgbGlicmFyeSA9ICJpb24iLAojICAgbWFya2VyQ29sb3IgPSBpbm5vdmFyOjppbm5vdmFfcGFsKCJlY29tc3QiLCByZXZlcnNlID0gVFJVRSkoMTcpCiMgKQoKY29tbXVuaXRpZXNfc2YgPC0gY29tbXVuaXRpZXNfc2YgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfY29tbXVuaXR5ID0gc3RyX3RvX3RpdGxlKGZmaV9oX2NvbW11bml0eSkKICApICU+JQogIGxlZnRfam9pbigKICAgIGZmaV9ob3VzZWhvbGQgJT4lCiAgICAgIHNlbGVjdChmZmlfaF9kaXN0cmljdCwgZmZpX2hfY29kZV9jb21tdW5pdHkpICU+JQogICAgICBkaXN0aW5jdCgpCiAgKSAgJT4lCiAgbXV0YXRlKAogICAgZmZpX2hfY29tbXVuaXR5X2xhYmVsID0gcGFzdGUwKAogICAgICBmZmlfaF9jb21tdW5pdHksCiAgICAgICIgKCIsCiAgICAgIHN0cl90b190aXRsZShmZmlfaF9kaXN0cmljdCksCiAgICAgICIpIgogICAgKQogICkKCgoKaG91c2Vob2xkX2NvbW11bml0aWVzX2xlYWZ0IDwtIGZmaV9ob3VzZWhvbGRfZ3BzICU+JQogIGxlYWZsZXQoKSAlPiUKICBhZGRQcm92aWRlclRpbGVzKAogICAgcHJvdmlkZXJzJE9wZW5TdHJlZXRNYXAsCiAgICBncm91cCA9ICJPcGVuU3RyZWV0TWFwIgogICkgJT4lCiAgYWRkQ2lyY2xlTWFya2VycygKICAgIGxheWVySWQgPSB+ZmZpX2hfaG91c2Vob2xkX2lkLAogICAgbGFiZWwgPSB+ZmZpX2lzX2NvZF9jb21fbGFiZWwsCiAgICBjb2xvciA9IH4gcGFsKHJlY2VudF9leHBvc3VyZSksCiAgICBncm91cCA9ICJIb3VzZWhvbGRzIiwKICAgIHJhZGl1cyA9IDcsCiAgICB3ZWlnaHQgPSA1LAogICAgb3BhY2l0eSA9IDEsCiAgICBmaWxsT3BhY2l0eSA9IDAuMSwKICAgIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucygKICAgICAgc3R5bGUgPSBsaXN0KAogICAgICAgICJmb250LXdlaWdodCIgPSAiYm9sZCIsCiAgICAgICAgcGFkZGluZyA9ICIzcHggOHB4IgogICAgICApLAogICAgICB0ZXh0c2l6ZSA9ICIxMnB4IiwKICAgICAgZGlyZWN0aW9uID0gImF1dG8iCiAgICApCiAgKSAlPiUKICAjIGFkZExlZ2VuZCgKICAjICAgdGl0bGUgPSAiUmVjZW50IEV4cG9zdXJlIiwKICAjICAgcGFsID0gcGFsLCAKICAjICAgdmFsdWVzID0gfiByZWNlbnRfZXhwb3N1cmUsIAogICMgICBncm91cCA9ICJjaXJjbGVzIiwgCiAgIyAgIHBvc2l0aW9uID0gImJvdHRvbWxlZnQiLAogICMgICB0cmFuc2Zvcm0gPSB+IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKICAjICAgb3BhY2l0eSA9IDEKICAjICkgJT4lPGZvbnQtYXdlc29tZS1pY29uIGljb249ImZhLXNvbGlkIGZhLWxvY2F0aW9uLWRvdCIgLz4KICBsZWFmbGVnZW5kOjphZGRMZWdlbmROdW1lcmljKAogICAgdGl0bGUgPSAiUmVjZW50IEV4cG9zdXJlIiwKICAgIHBhbCA9IHBhbCwKICAgIHZhbHVlcyA9IH4gcmVjZW50X2V4cG9zdXJlLAogICAgcG9zaXRpb24gPSAiYm90dG9tcmlnaHQiLAogICAgb3JpZW50YXRpb24gPSAiaG9yaXpvbnRhbCIsCiAgICBoZWlnaHQgPSAyMCwKICAgIHdpZHRoID0gMTAwLAogICAgZGVjcmVhc2luZyA9IEZBTFNFLAogICAgbnVtYmVyRm9ybWF0ID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdCgpLAogICAgZ3JvdXAgPSAiY2lyY2xlcyIKICApICAlPiUKICBhZGRBd2Vzb21lTWFya2VycygKICAgIGRhdGEgPSBjb21tdW5pdGllc19zZiwKICAgIGxheWVySWQgPSB+ZmZpX2hfY29kZV9jb21tdW5pdHksCiAgICBsYWJlbCA9IH5mZmlfaF9jb21tdW5pdHlfbGFiZWwsCiAgICBncm91cCA9ICJDb21tdW5pdGllcyIKICApICU+JQogIGFkZFByb3ZpZGVyVGlsZXMoCiAgICBwcm92aWRlcnMkT3BlblN0cmVldE1hcCwKICAgIGdyb3VwID0gIk9wZW5TdHJlZXRNYXAiCiAgKSAlPiUKICBhZGRUaWxlcygKICAgIHVybFRlbXBsYXRlID0gImh0dHA6Ly9tdDAuZ29vZ2xlLmNvbS92dC9seXJzPW0maGw9ZW4meD17eH0meT17eX0mej17en0mcz1HYSIsCiAgICBhdHRyaWJ1dGlvbiA9ICJHb29nbGUgTWFwcyIsCiAgICBvcHRpb25zID0gbGVhZmxldDo6dGlsZU9wdGlvbnMoCiAgICAgIG1heE5hdGl2ZVpvb20gPSAxOSwKICAgICAgbWF4Wm9vbSA9IDIwCiAgICApLAogICAgZ3JvdXAgPSAiR29vZ2xlIE1hcHMiCiAgKSAlPiUKICBhZGRUaWxlcygKICAgIHVybFRlbXBsYXRlID0gImh0dHBzOi8vbXQxLmdvb2dsZS5jb20vdnQvbHlycz1zJng9e3h9Jnk9e3l9Jno9e3p9IiwKICAgIGF0dHJpYnV0aW9uID0gIlNhdGVsbGl0ZSBWaWV3IiwKICAgIG9wdGlvbnMgPSBsZWFmbGV0Ojp0aWxlT3B0aW9ucygKICAgICAgbWF4TmF0aXZlWm9vbSA9IDE5LAogICAgICBtYXhab29tID0gMjAKICAgICksCiAgICBncm91cCA9ICJTYXRlbGxpdGUgVmlldyIKICApICU+JQogICMgTGF5ZXJzIGNvbnRyb2wqCiAgYWRkTGF5ZXJzQ29udHJvbCgKICAgIG92ZXJsYXlHcm91cHMgPSBjKCJIb3VzZWhvbGRzIiwgIkNvbW11bml0aWVzIiksCiAgICBiYXNlR3JvdXBzID0gYygiT3BlblN0cmVldE1hcCIsICJHb29nbGUgTWFwcyIsICJTYXRlbGxpdGUgVmlldyIpLAogICAgb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKQogICkgJT4lCiAgIyBhZGRMZWdlbmQoCiAgIyAgICJ0b3ByaWdodCIsCiAgIyAgIHBhbCA9IGlubm92YXI6Omlubm92YV9wYWwoImVjb21zdCIsIHJldmVyc2UgPSBUUlVFKSg5ODApCiAgIyApICAlPiUKICAjIGFkZExlZ2VuZCgKICAjICAgcG9zaXRpb24gPSAiYm90dG9tcmlnaHQiLAogICMgICBjb2xvcnMgPSBjKAogICMgICAgICJ3aGl0ZTsgd2lkdGg6MTVweDsgaGVpZ2h0OjE1cHg7CiAgIyAgICAgICAgICAgICAgICBib3JkZXI6NXB4IHNvbGlkIHJlZDsgYm9yZGVyLXJhZGl1czo1MCU7IiwKICAjICAgICAid2hpdGU7IHdpZHRoOjcuNXB4OyBoZWlnaHQ6Ny41cHg7IG1hcmdpbi10b3A6IDVweDsKICAjICAgICAgICAgICAgICAgIGJvcmRlcjo1cHggc29saWQgYmxhY2s7IGJvcmRlci1yYWRpdXM6NTAlOyBtYXJnaW4tbGVmdDoycHg7IgogICMgICApLAogICMgICBsYWJlbHMgPSBjKAogICMgICAgICI8ZGl2IHN0eWxlPSdkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGhlaWdodDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi10b3A6IDhweDtsaW5lLWhlaWdodDogMTBweDtmb250LXdlaWdodDogYm9sZDsKICAjICAgICAgICAgICAgICAgIGNvbG9yOiBibGFjazsgJz5BdCBsZWFzdCAxIHBlcnNvbiB3aXRoIHJlY2VudCBtYWxhcmlhPC9kaXY+IiwKICAjICAgICAiPGRpdiBzdHlsZT0nZGlzcGxheTogaW5saW5lLWJsb2NrO2hlaWdodDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi10b3A6IDhweDtsaW5lLWhlaWdodDogMTBweDtmb250LXdlaWdodDogYm9sZDsKICAjICAgICAgICAgICAgICAgIGNvbG9yOiBibGFjazsgbWFyZ2luLXRvcDogMTBweDsKICAjICAgICAgICAgICAgICAgIG1hcmdpbi1sZWZ0OjVweCc+Tm8gb25lIHdpdGggcmVjZW50IG1hbGFyaWEgYXQgaG91c2Vob2xkPC9kaXY+IgogICMgICApLAogICMgICBvcGFjaXR5ID0gMQogICMgKSAlPiUKICBsZWFmbGV0LmV4dHJhczo6YWRkUmVzZXRNYXBCdXR0b24oKQpgYGAKCgpgYGB7ciBldmFsPUZBTFNFfQpodG1sd2lkZ2V0czo6c2F2ZVdpZGdldCgKICBob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQsCiAgZmlsZSA9ICIuLzAyX291dHB1dC9wbG90cy9ob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQuaHRtbCIKKQoKd2Vic2hvdDo6d2Vic2hvdCgKICAiLi8wMl9vdXRwdXQvcGxvdHMvaG91c2Vob2xkX2NvbW11bml0aWVzX2xlYWZ0Lmh0bWwiLAogICIuLzAyX291dHB1dC9wbG90cy9ob3VzZWhvbGRfY29tbXVuaXRpZXNfbGVhZnQucG5nIiwKICBjbGlwcmVjdCA9ICJ2aWV3cG9ydCIsCiAgem9vbSA9IDQKKQpgYGA=